auto assign arguments?

Discussion in 'Ruby' started by David Chelimsky, Jan 18, 2007.

  1. I see where to put bugs and patches, but this is a feature request. Is
    this the right place to submit these?

    In any case, here's a feature request:

    I find that I do a lot of this:

    def initialize(thing, other)
    @thing = thing
    @other = other
    end

    One thing I'd love to see in a future version of ruby is this;

    def initialize(@thing, @other)
    end

    ... and have that automagically initialize @thing and @other with the
    submitted values.

    Thanks,
    David
     
    David Chelimsky, Jan 18, 2007
    #1
    1. Advertising

  2. David Chelimsky

    Kalman Noel Guest

    David Chelimsky:
    > One thing I'd love to see in a future version of ruby is this;
    >
    > def initialize(@thing, @other)
    > end


    Try the following. Note that it does not actually set @thing and @other
    - they are only accessible methodically - but gives you an appropriate
    #initialize.

    Klass = Struct.new:)thing, :eek:ther)
    class Klass

    # more

    end

    Kalman
     
    Kalman Noel, Jan 18, 2007
    #2
    1. Advertising

  3. David Chelimsky

    Guest

    On Jan 18, 2007, at 3:13 PM, David Chelimsky wrote:
    > One thing I'd love to see in a future version of ruby is this;
    >
    > def initialize(@thing, @other)
    > end


    Well, you can get pretty close...

    def initialize(*a)
    @thing, @other = *a
    end

    You don't get method arity checking that way but...

    def initialize(a,b)
    @thing, @other = a,b
    end

    isn't too bad either.

    As for as official change requests see: http://rcrchive.net/

    Gary Wright
     
    , Jan 18, 2007
    #3
  4. On Jan 18, 2007, at 2:13 PM, David Chelimsky wrote:

    > I see where to put bugs and patches, but this is a feature request. Is
    > this the right place to submit these?
    >
    > In any case, here's a feature request:
    >
    > I find that I do a lot of this:
    >
    > def initialize(thing, other)
    > @thing = thing
    > @other = other
    > end
    >
    > One thing I'd love to see in a future version of ruby is this;
    >
    > def initialize(@thing, @other)
    > end
    >
    > ... and have that automagically initialize @thing and @other with the
    > submitted values.


    Some thinking-out-loud:

    #!/usr/bin/env ruby -w

    class Module
    def constructor(*attrs)
    define_method:)initialize) do |*passed|
    raise ArgumentError, "Wrong number of arguments" \
    unless attrs.size == passed.size

    attrs.each_with_index do |att, i|
    instance_variable_set("@#{att}", passed)
    end

    after_initialize if respond_to? :after_initialize
    end
    end
    end

    class ABC
    constructor :a, :b, :c

    def after_initialize
    p instance_variables.map { |var| [var, instance_variable_get
    (var)] }.sort
    end
    end

    ABC.new(1, :two, "three")
    ABC.new(*%w[testing my code])
    # >> [["@a", 1], ["@b", :two], ["@c", "three"]]
    # >> [["@a", "testing"], ["@b", "my"], ["@c", "code"]]

    __END__

    James Edward Gray II
     
    James Edward Gray II, Jan 18, 2007
    #4
  5. David Chelimsky

    Pit Capitain Guest

    David Chelimsky schrieb:
    > I find that I do a lot of this:
    >
    > def initialize(thing, other)
    > @thing = thing
    > @other = other
    > end
    >
    > One thing I'd love to see in a future version of ruby is this;
    >
    > def initialize(@thing, @other)
    > end


    Not that I would do it, but:

    class C
    define_method :initialize do |@x, @y|
    end
    end

    c = C.new 1, 2
    p c # => #<C:0x2aeabd0 @y=2, @x=1>

    I think Matz is planning to deprecate this feature.

    Regards,
    Pit
     
    Pit Capitain, Jan 18, 2007
    #5
  6. David Chelimsky

    Guest

    On Fri, 19 Jan 2007, Pit Capitain wrote:

    > David Chelimsky schrieb:
    >> I find that I do a lot of this:
    >>
    >> def initialize(thing, other)
    >> @thing = thing
    >> @other = other
    >> end
    >>
    >> One thing I'd love to see in a future version of ruby is this;
    >>
    >> def initialize(@thing, @other)
    >> end

    >
    > Not that I would do it, but:
    >
    > class C
    > define_method :initialize do |@x, @y|
    > end
    > end
    >
    > c = C.new 1, 2
    > p c # => #<C:0x2aeabd0 @y=2, @x=1>
    >
    > I think Matz is planning to deprecate this feature.
    >
    > Regards,
    > Pit


    harp:~ > cat a.rb
    require 'rubygems'
    require 'attributes'

    class C
    attributes %w( a b c )

    def initialize *argv
    self.class.attributes.zip(argv){|a,v| send a, v}
    end
    end

    p(C.new(0,1,2))

    harp:~ > ruby a.rb
    #<C:0xb74c1b44 @c=2, @b=1, @a=0>


    -a
    --
    in the practice of tolerance, one's enemy is the best teacher.
    - the dalai lama
     
    , Jan 18, 2007
    #6
  7. David Chelimsky wrote:
    > I see where to put bugs and patches, but this is a feature request. Is
    > this the right place to submit these?
    >
    > In any case, here's a feature request:
    >
    > I find that I do a lot of this:
    >
    > def initialize(thing, other)
    > @thing = thing
    > @other = other
    > end
    >
    > One thing I'd love to see in a future version of ruby is this;
    >
    > def initialize(@thing, @other)
    > end
    >
    > .. and have that automagically initialize @thing and @other with the
    > submitted values.


    I could have sworn Paul Brannan did this as part of RubyTreasures, but
    I don't see any such thing mentioned in the docs. I know it's been
    done somewhere as a language hack.

    Personally, I think it ought to be the default behavior, since it's
    what you want about 80% of the time in practice I think. At worst,
    you've got a couple of useless instance variables that people would
    have to go to pains to get at via instance_variable_get. Heck, why not
    take this a step further and create automatic getters and setters? You
    can always undef or redefine them.

    Regards,

    Dan
     
    Daniel Berger, Jan 18, 2007
    #7
  8. On 1/18/07, <> wrote:
    > On Fri, 19 Jan 2007, Pit Capitain wrote:
    >
    > > David Chelimsky schrieb:
    > >> I find that I do a lot of this:
    > >>
    > >> def initialize(thing, other)
    > >> @thing = thing
    > >> @other = other
    > >> end
    > >>
    > >> One thing I'd love to see in a future version of ruby is this;
    > >>
    > >> def initialize(@thing, @other)
    > >> end

    > >
    > > Not that I would do it, but:
    > >
    > > class C
    > > define_method :initialize do |@x, @y|
    > > end
    > > end
    > >
    > > c = C.new 1, 2
    > > p c # => #<C:0x2aeabd0 @y=2, @x=1>
    > >
    > > I think Matz is planning to deprecate this feature.
    > >
    > > Regards,
    > > Pit

    >
    > harp:~ > cat a.rb
    > require 'rubygems'
    > require 'attributes'
    >
    > class C
    > attributes %w( a b c )
    >
    > def initialize *argv
    > self.class.attributes.zip(argv){|a,v| send a, v}
    > end
    > end
    >
    > p(C.new(0,1,2))
    >
    > harp:~ > ruby a.rb
    > #<C:0xb74c1b44 @c=2, @b=1, @a=0>
    >


    Thanks for all the responses, but I'm really looking for something
    that feels simple and explicit (these suggestions all feel a little
    magical and confusing).

    Do any of you think this would be a good or bad thing to add to the
    language? I'd like to post an RCR, but the RCRchive warns against
    poorly researched requests - so I'd like to do some research ;) My
    feeling is that my proposal would add a very simple and explicit means
    of assigning those args that you wish to assign. What's yours?

    Thanks,
    David
     
    David Chelimsky, Jan 18, 2007
    #8
  9. On Jan 18, 2007, at 3:35 PM, Daniel Berger wrote:

    > Heck, why not
    > take this a step further and create automatic getters and setters? You
    > can always undef or redefine them.


    I would really be against that. If you do that, there's no point in
    how Ruby currently has all instance data as private. It blows
    encapsulation wide open and being very against the spirit of OO just
    doesn't feel Rubyish to me.

    James Edward Gray II
     
    James Edward Gray II, Jan 18, 2007
    #9
  10. On 1/18/07, James Edward Gray II <> wrote:

    > I would really be against that. If you do that, there's no point in
    > how Ruby currently has all instance data as private. It blows
    > encapsulation wide open and being very against the spirit of OO just
    > doesn't feel Rubyish to me.


    +1,

    BUT... it's be okay if you could build this as a module, I think.
    Then you could just include it in a class to get the behavior when it
    is appropriate.
     
    Gregory Brown, Jan 18, 2007
    #10
  11. James Edward Gray II wrote:
    > On Jan 18, 2007, at 3:35 PM, Daniel Berger wrote:
    >
    > > Heck, why not
    > > take this a step further and create automatic getters and setters? You
    > > can always undef or redefine them.

    >
    > I would really be against that. If you do that, there's no point in
    > how Ruby currently has all instance data as private. It blows
    > encapsulation wide open and being very against the spirit of OO just
    > doesn't feel Rubyish to me.


    Hm, you're probably right.

    I suppose it would require some fundamental changes to the language,
    i.e. not allowing instance data to be set directly outside of the
    constructor (forcing you to use the actual getter and setter methods
    outside of the constructor). This is what Fortress does, and I think
    it's what Perl 6 will do as well.

    I'm not sure what the downside of that change would be, other than a
    forced method lookup. I don't know enough about Ruby internals to know
    if "@foo = 1" is cheaper than "foo = 1", but I'm guessing that it is.

    Forgive me, for I have been tainted by the Fortress language recently.
    :)

    Regards,

    Dan
     
    Daniel Berger, Jan 18, 2007
    #11
  12. David Chelimsky

    Guest

    On Jan 18, 2007, at 5:06 PM, Gregory Brown wrote:
    > BUT... it's be okay if you could build this as a module, I think.
    > Then you could just include it in a class to get the behavior when it
    > is appropriate.


    The code below uses instance_exec from ruby 1.9. It will still work
    under ruby 1.8 as long as you don't give a block to the #init method.

    Gary Wright

    module Init
    def init(*syms, &iproc)
    define_method:)initialize) {|*x|
    raise ArgumentError, "wrong number of arguments: #{x.size} for
    #{syms.size}" if x.size != syms.size
    syms.zip(x).each { |sym, val|
    instance_variable_set("@#{sym}", val)
    }
    instance_exec(*x, &iproc) if iproc
    }
    end
    end

    class A
    extend Init
    init :a, :b, :c, :d
    end

    a = A.new(1,2,3,4)
    p a.instance_variables # ["@b", "@a", "@c", "@d"]
    a.instance_variables.each { |n|
    puts "#{n} = #{a.instance_variable_get(n)}"
    }

    class Object
    extend Init
    end

    class B
    attr :attr1, :attr2
    init :attr1, :attr2
    end

    b = B.new('foo', 'bar')
    p b.attr1 # 'foo'
    p b.attr2 # 'bar'

    class C
    init :c, :d do
    puts "@c is #{@c}"
    puts "@d is #{@d}"
    end
    end

    C.new(3,4) # @c is 3
    # @d is 4
    begin
    C.new(5) # argument error
    rescue
    p $!
    end
     
    , Jan 18, 2007
    #12
  13. Wow. You guys are all coming up w/ great alternatives, but would
    somebody please just answer my question? I am not asking for ways to
    do what I want. I'm asking if you think the following proposed syntax
    addition would be useful:

    Any parameter preceded by a @ results in an instance variable being
    created and initialized with the submitted value. So:

    class MyClass
    def initialize(@a)
    end
    end

    instance = MyClass.new(5)
    #results in an instance variable @a with a value of 5

    This would apply to any parameter in the list, including those with
    default values.

    MyClass
    def initialize(@a, @b=3)
    end
    end

    instance = MyClass.new(5)
    #results in an instance @a = 5 and @b = 3

    instance = MyClass.new(5, 4)
    #results in an instance @a = 5 and @b = 4

    Does this seem like a good thing to propose?

    Thank you,
    David
     
    David Chelimsky, Jan 18, 2007
    #13
  14. On 1/18/07, David Chelimsky <> wrote:

    > Does this seem like a good thing to propose?


    -1. I see @a and @b to be part of the classe's instance variables, so
    this syntactic sugar.
     
    Gregory Brown, Jan 18, 2007
    #14
  15. On 1/18/07, Gregory Brown <> wrote:
    > On 1/18/07, David Chelimsky <> wrote:
    >
    > > Does this seem like a good thing to propose?

    >
    > -1. I see @a and @b to be part of the classe's instance variables, so
    > this syntactic sugar.


    <whoops>

    This syntactic sugar would confuse me.
     
    Gregory Brown, Jan 18, 2007
    #15
  16. David Chelimsky

    Bill Kelly Guest

    From: "David Chelimsky" <>
    >
    > Any parameter preceded by a @ results in an instance variable being
    > created and initialized with the submitted value. So:
    >
    > class MyClass
    > def initialize(@a)
    > end
    > end
    >
    > instance = MyClass.new(5)
    > #results in an instance variable @a with a value of 5


    As I recall, this was proposed on this list several years ago.

    I think it generated a bit of discussion, with possibly even
    some comments by Matz.

    Sorry, I don't have a link to the thread in the archives,
    though...


    Regards,

    Bill
     
    Bill Kelly, Jan 18, 2007
    #16
  17. Gregory Brown wrote:
    > On 1/18/07, David Chelimsky <> wrote:
    >
    >> Does this seem like a good thing to propose?

    >
    > -1. I see @a and @b to be part of the classe's instance variables, so


    Why the class' instance variables? That doesn't fit with the current pattern:

    class C
    def initialize(v = nil)
    @default = v
    end
    def otherdefault
    42
    end
    def ultimate(v = @default || otherdefault)
    v
    end
    end
    C.new.ultimate #=> 42
    C.new(54).ultimate #=> 54

    If an object's instance variables (and even methods) can be used as default
    values, it would be coherent to also allow them in the argument list. This feels
    100% instinctive to me.

    +1

    -dd
     
    Daniel DeLorme, Jan 19, 2007
    #17
  18. David Chelimsky

    Bill Kelly Guest

    From: "Bill Kelly" <>
    >
    > From: "David Chelimsky" <>
    >>
    >> Any parameter preceded by a @ results in an instance variable being
    >> created and initialized with the submitted value. So:
    >>
    >> class MyClass
    >> def initialize(@a)
    >> end
    >> end
    >>
    >> instance = MyClass.new(5)
    >> #results in an instance variable @a with a value of 5

    >
    > As I recall, this was proposed on this list several years ago.


    Found it... Wow, that _was_ awhile ago. <grin>

    http://groups.google.com/group/comp.lang.ruby/browse_frm/thread/18465d51fb34fb98/4a0a63976cbe3ea9



    HTH,

    Bill
     
    Bill Kelly, Jan 19, 2007
    #18
  19. On 18.01.2007 21:25, Kalman Noel wrote:
    > David Chelimsky:
    >> One thing I'd love to see in a future version of ruby is this;
    >>
    >> def initialize(@thing, @other)
    >> end

    >
    > Try the following. Note that it does not actually set @thing and @other
    > - they are only accessible methodically - but gives you an appropriate
    > #initialize.
    >
    > Klass = Struct.new:)thing, :eek:ther)
    > class Klass
    >
    > # more
    >
    > end


    You can even do

    Klass = Struct.new :foo, :bar do
    def some_method
    end
    end

    which I find pretty nice. :)

    robert
     
    Robert Klemme, Jan 19, 2007
    #19
  20. David Chelimsky

    Guest

    Hi --

    On Fri, 19 Jan 2007, David Chelimsky wrote:

    > Wow. You guys are all coming up w/ great alternatives, but would
    > somebody please just answer my question? I am not asking for ways to
    > do what I want. I'm asking if you think the following proposed syntax
    > addition would be useful:
    >
    > Any parameter preceded by a @ results in an instance variable being
    > created and initialized with the submitted value. So:
    >
    > class MyClass
    > def initialize(@a)
    > end
    > end
    >
    > instance = MyClass.new(5)
    > #results in an instance variable @a with a value of 5


    That was proposed as an RCR and rejected; see
    http://oldrcrs.rubypal.com/rejected.html#rcr3


    David

    --
    Q. What is THE Ruby book for Rails developers?
    A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)
    (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf)
    Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
    A. Ruby Power and Light, LLC (http://www.rubypal.com)
     
    , Jan 19, 2007
    #20
    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. =?Utf-8?B?V2FyYW4=?=

    Auto-Suggested Textbox like google auto suggest

    =?Utf-8?B?V2FyYW4=?=, Apr 20, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    8,559
    inrakeshworld
    Jul 27, 2007
  2. Edward Diener
    Replies:
    14
    Views:
    5,084
    Josiah Carlson
    Apr 6, 2004
  3. Neo
    Replies:
    10
    Views:
    692
    sushant
    Jan 20, 2005
  4. tutmann
    Replies:
    4
    Views:
    454
  5. linkswanted
    Replies:
    1
    Views:
    970
Loading...

Share This Page