[ANN] NamedParameters v0.0.0 ('first', :second => 'release')

Discussion in 'Ruby' started by Roger Pack, Jul 18, 2008.

  1. Roger Pack

    Roger Pack Guest

    NamedParameters
    is a library for (MRI) ruby 1.8.x that allows you to call a method
    with or without named parameters.

    Introduction

    One thing that is notably lacking from Ruby is the ability to
    arbitrarily call methods with named parameters.

    Ex in this code:

    class A
    def method_with_lots_of_parameters param1, p2, p3, p4 = 5, p6 = 7, p7
    = 8, p9 = 900
    p7
    end
    end
    A.new.method_with_lots_of_parameters 1, 2, 3, 4, 5, 6, 7

    can anybody guess what p7 will be when you run this? (a contrived
    example, but an example nonetheless).

    Previous attempts to overcome this have dealt with using a hash for the
    ending argument, and/or *args for parameters. These are somewhat tedious
    and also a little error prone, as misspellations aren't immediately
    caught at run-time in the hash example, and parsing is annoying in the
    *args example.

    Enter named parameters.

    With named parameters, you can define your method as you normally would,
    and add one line:

    class A
    def method_with_lots_of_parameters param1, p2, p3, p4 = 5, p6 = 7, p7
    = 8, p9 = 900
    p7
    end
    # and add this line
    create_named_parameters_wrapper :method_with_lots_of_parameters
    end

    and now you can call it like

    A.new.method_with_lots_of_parameters 1, 2, 3, 4, :p7 => 6

    And it works as you'd expect.

    How it works

    It works by creating (in our example above) code equivalent to:

    class A
    # save away the original function
    alias :_method_with_lots_of_parameters :method_with_lots_of_parameters

    def method_with_lots_of_parameters *args
    param1, p2, p3, p4, p6, p7, p9 = args.interpret [:param1, :p2,
    :p3], :p4, :p6, :p7, :p9 # parses what you passed it, using the last
    hash for named parameters
    if p4 == :__not_assigned
    p4 = 5
    end
    if p6 == :__not_assigned
    p6 = 7
    if p9 == :__not_assigned
    p9 = 900
    end
    _method_with_lots_of_parameters param1, p2, p3, p4, p6, p7, p9 #
    call the original function
    end
    end

    Note also that class methods need to be called preceded by 'self.', like

    class A
    def A.class_method1
    end
    create_named_parameters_wrapper :'self.class_method1'
    end
    [to satisfy parseTree's semantics.]

    Also note that you must continue naming parameters once you start naming
    them.
    [i.e. method_with_lots_of_parameters :param1 => 2, 2, 3 is not allowed],
    to help disambiguate which parameter is which [idea stolen from Python].

    Many thanks to the parse tree and ruby2ruby crew for making this
    possible.

    In my own use of it I have seen increased code readability and
    understandability, especially for methods that take more than a few
    parameters.

    Note also that if your current method takes an ending hash then this
    won't work, as it uses the ending hash for named parameters.

    How to install

    sudo gem install ruby2ruby # pre requisite
    svn co
    http://ruby-roger-useful-functions.googlecode.com/svn/trunk/arg_parser/v2
    named_args
    require 'named_args/create_named_parameters_wrapper'
    ... # code as usual, adding create_named_parameters_wrapper calls to
    functions you'd like to be able to have this functionality.

    Feedback welcome.

    This is just an early release as I wanted to publish in case it were
    useful to anyone.

    Take care.
    =R
    --
    Posted via http://www.ruby-forum.com/.
     
    Roger Pack, Jul 18, 2008
    #1
    1. Advertising

  2. Roger Pack

    ara.t.howard Guest

    On Jul 17, 2008, at 10:54 PM, Roger Pack wrote:

    >
    > This is just an early release as I wanted to publish in case it were
    > useful to anyone.



    i did something vaguely similar a while back

    http://codeforpeople.com/lib/ruby/parseargs/parseargs-0.3.0/README

    but didn't end up using it much. thought you might be interested in
    the ideas or impl - your project looks quite interesting - 3 cheers
    for ruby2ruby.

    regards.

    a @ http://codeforpeople.com/
    --
    we can deny everything, except that we have the possibility of being
    better. simply reflect on that.
    h.h. the 14th dalai lama
     
    ara.t.howard, Jul 18, 2008
    #2
    1. Advertising

  3. Roger Pack

    Roger Pack Guest

    Re: NamedParameters v0.0.0 ('first', :second => 'release')


    > i did something vaguely similar a while back
    >
    > http://codeforpeople.com/lib/ruby/parseargs/parseargs-0.3.0/README
    >
    > but didn't end up using it much. thought you might be interested in
    > the ideas or impl - your project looks quite interesting - 3 cheers
    > for ruby2ruby.



    Cool stuff. I had never thought of incrementing type conversions.
    Haven't done anything like that since I built a VM back at BYU in the
    undergrad years :p

    Class checking also has potential. I'll poke around there and steal
    some code sometime if anyone gets around to wanting that feature.

    I think you and I both ran into similar problems with constructing this
    type of thing. It ends up being somewhat unnatural to use [hopefully
    less so with the latest incantation] :)


    I did notice that Matz apparently plans on using something very similar
    to an ending hash for named parameters for 2.0 [1].
    We'll have to see what the future holds.

    =R

    [1]
    http://holtsblog.blogspot.com/2008/02/ruby-19-talk-by-matz-matsumoto-22208.html
    --
    Posted via http://www.ruby-forum.com/.
     
    Roger Pack, Jul 18, 2008
    #3
  4. Roger Pack

    ThoML Guest

    Re: NamedParameters v0.0.0 ('first', :second => 'release')

    > I did notice that Matz apparently plans on using something very similar
    > to an ending hash for named parameters for 2.0 [1].


    I think what was meant is this:

    def foo(a, args)
    p a, args[:b], args[:c] || 'nope', args[:d] || 'yepp'
    end
    foo 1, :d => 4, :c => 3

    In ruby 1.9, due to the new hash syntax, this can be also written as:
    foo 1, d: 4, c: 3

    Which almost looks like names arguments.
     
    ThoML, Jul 18, 2008
    #4
  5. Roger Pack

    Roger Pack Guest

    Re: NamedParameters v0.0.0 ('first', :second => 'release')

    ThoML wrote:
    > I think what was meant is this:
    >
    > def foo(a, args)
    > p a, args[:b], args[:c] || 'nope', args[:d] || 'yepp'
    > end
    > foo 1, :d => 4, :c => 3
    >
    > In ruby 1.9, due to the new hash syntax, this can be also written as:
    > foo 1, d: 4, c: 3
    >
    > Which almost looks like names arguments.


    Possibly. Kind of hard to tell from interview transcript notes :)
    My hope is that it'll be more than just ending hash based, but will
    support naming the variable names themselves.

    def foo(a, b)
    end

    foo 3, b: 4

    Thanks!
    -R
    --
    Posted via http://www.ruby-forum.com/.
     
    Roger Pack, Jul 18, 2008
    #5
  6. Roger Pack

    ara.t.howard Guest

    Re: NamedParameters v0.0.0 ('first', :second => 'release')

    On Jul 18, 2008, at 3:13 PM, Roger Pack wrote:

    >
    > Possibly. Kind of hard to tell from interview transcript notes :)
    > My hope is that it'll be more than just ending hash based, but will
    > support naming the variable names themselves.
    >
    > def foo(a, b)
    > end
    >
    > foo 3, b: 4


    IDL does this and it's a pain for most situations, for instance

    def foo a, b
    bar( ... )
    end

    def bar b, a
    end

    foo a : 4, b : 2

    now foo has to have a method to return the named vars to bar, kinda
    like *argv, but much more sophisticated, drastically reducing the
    ability the sling around arrays and hashes in methods, especially for
    method forwarding. then there is the issue of required vs optional
    parameters... and code like this

    def foo options = {}
    add_defaults_to options
    bar options
    end

    etc

    basically i've personally found languages with real named parameters
    leaving me wishing they were simply hash based. my 2 cts.

    a @ http://codeforpeople.com/
    --
    we can deny everything, except that we have the possibility of being
    better. simply reflect on that.
    h.h. the 14th dalai lama
     
    ara.t.howard, Jul 18, 2008
    #6
  7. Roger Pack

    Roger Pack Guest

    Re: NamedParameters v0.0.0 ('first', :second => 'release')

    > IDL does this and it's a pain for most situations, for instance
    >
    > def foo a, b
    > bar( ... )
    > end
    >
    > def bar b, a
    > end
    >
    > foo a : 4, b : 2
    >
    > now foo has to have a method to return the named vars to bar, kinda
    > like *argv, but much more sophisticated, drastically reducing the
    > ability the sling around arrays and hashes in methods, especially for
    > method forwarding. then there is the issue of required vs optional
    > parameters... and code like this
    >
    > def foo options = {}
    > add_defaults_to options
    > bar options
    > end
    >
    > etc


    Yeah it definitely would reduce the ability to have ones own ending
    hash.
    That being said, you can always just pass on arguments in the standard
    way, a la

    def foo(a, b)
    bar(a, b)
    end

    But how that would interplay with *args, I don't know.

    My recommendation would be to be able to specify which methods have
    named arguments, so you know to expect them, and how to deal with them.
    Thoughts?


    :)
    -R

    >
    > basically i've personally found languages with real named parameters
    > leaving me wishing they were simply hash based. my 2 cts.
    >
    > a @ http://codeforpeople.com/


    --
    Posted via http://www.ruby-forum.com/.
     
    Roger Pack, Jul 19, 2008
    #7
  8. Roger Pack

    ara.t.howard Guest

    Re: NamedParameters v0.0.0 ('first', :second => 'release')

    On Jul 19, 2008, at 3:13 PM, Roger Pack wrote:

    > My recommendation would be to be able to specify which methods have
    > named arguments, so you know to expect them, and how to deal with
    > them.
    > Thoughts?
    >
    >
    > :)


    no thoughts other than: 'better matz than me!'

    cheers.

    a @ http://codeforpeople.com/
    --
    we can deny everything, except that we have the possibility of being
    better. simply reflect on that.
    h.h. the 14th dalai lama
     
    ara.t.howard, Jul 19, 2008
    #8
  9. Roger Pack

    Trans Guest

    Re: NamedParameters v0.0.0 ('first', :second => 'release')

    On Jul 19, 5:13=A0pm, Roger Pack <> wrote:
    > > IDL does this and it's a pain for most situations, for instance

    >
    > > def foo a, b
    > > =A0 =A0bar( ... )
    > > end

    >
    > > def bar b, a
    > > end

    >
    > > foo a : 4, b : 2

    >
    > > now foo has to have a method to return the named vars to bar, kinda
    > > like *argv, but much more sophisticated, drastically reducing the
    > > ability the sling around arrays and hashes in methods, especially for
    > > method forwarding. =A0then there is the issue of required vs optional
    > > parameters... =A0and code like this

    >
    > > =A0 =A0def foo options =3D {}
    > > =A0 =A0 =A0add_defaults_to options
    > > =A0 =A0 =A0bar options
    > > =A0 =A0end

    >
    > > etc

    >
    > Yeah it definitely would reduce the ability to have ones own ending
    > hash.
    > That being said, you can always just pass on arguments in the standard
    > way, a la
    >
    > def foo(a, b)
    > =A0 bar(a, b)
    > end
    >
    > But how that would interplay with *args, I don't know.
    >
    > My recommendation would be to be able to specify which methods have
    > named arguments, so you know to expect them, and how to deal with them.
    > Thoughts?


    All I want is:

    def foo(*args, **keys)

    end

    I am sooooooooooooooooooooooooooooo tired of:

    def foo(*args_and_keys)
    keys =3D (Hash=3D=3D=3Dargs_and_keys.last ? args.pop : {})
    ...
    end

    T.
     
    Trans, Jul 20, 2008
    #9
  10. Roger Pack

    Roger Pack Guest

    Re: NamedParameters v0.0.0 ('first', :second => 'release')

    Trans wrote:
    > All I want is:
    >
    > def foo(*args, **keys)
    >
    > end
    >

    I could write you one that is
    class A
    def foo(args, keys)
    # keys is always a hash, args an array
    end

    def bar(args, keys)
    end

    create_args_keys_wrappers # creates wrappers for functions which have
    parameters named args and keys

    end

    If you'd like it (using ruby2ruby)
    -R
    --
    Posted via http://www.ruby-forum.com/.
     
    Roger Pack, Jul 20, 2008
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. holger krekel

    [ann] first release of PyPy

    holger krekel, May 20, 2005, in forum: Python
    Replies:
    38
    Views:
    876
    Rocco Moretti
    May 30, 2005
  2. Torsten Bronger

    ANN: PyVISA 0.9 (first public release)

    Torsten Bronger, Jun 30, 2005, in forum: Python
    Replies:
    0
    Views:
    369
    Torsten Bronger
    Jun 30, 2005
  3. Daniel Dyer
    Replies:
    4
    Views:
    477
    Daniel Dyer
    Sep 25, 2006
  4. Stef Mientki
    Replies:
    3
    Views:
    343
    Stef Mientki
    Jun 17, 2009
  5. yelipolok
    Replies:
    4
    Views:
    288
    John W. Krahn
    Jan 27, 2010
Loading...

Share This Page