Metaprograming question about initialize

How many times have we seen this:

class X
  attr_accessor :arg1, :arg2, :arg3, :arg4

  def initialize(arg1, arg2, arg3, arg4)
    @arg1, @arg2, @arg3, @arg4 = arg1, arg2, arg3, arg4
  end
end

Wouldn't it be nice if we (ok, I) could instead write

def initialize(arg1, arg2, arg3, arg4)
  initargs
end

and have initargs create the attr_accessor as well as the assignments.

I know I can do this in 1.9.2

class X
  def initialize(arg1)
    self.class.send(:attr_accessor, :arg1)
    @arg1 = arg1
  end
end

So is it possible in Ruby to introspect on the _names_ of arguments passed in to a function so that I can build the attr_accessor as well as the assignments?

You can use the Struct class, which implements exactly this.

-- Matma Rex

Perhaps you are looking for "Kernel#local_variables".

···

--
Posted via http://www.ruby-forum.com/.

Monday, February 20, 2012, 3:39:57 AM, you wrote:

You can use the Struct class, which implements exactly this.

-- Matma Rex

Bartosz,

What I want to do is not change the interface but the implementation. That is, I want to get a list of the names of the arguments by introspection.

Ralph

It is much simpler and IMO makes much more sense not to figure out
variable names while already having variables, but to figure out their
contents while having names. Like this:

class Class
  def attr_accessor_init *meths
    attr_accessor *meths
    define_method :initialize do |*args|
      meths.each_with_index do |m, i|
        self.send :"#{m}=", args[i]
      end
    end
  end
end

irb(main):013:0> class A
irb(main):014:1> attr_accessor_init :a, :b, :c
irb(main):015:1> end

irb(main):029:0> A.new 4, 6, 8
=> #<A:0xd6cb18 @a=4, @b=6, @c=8>

(This is, essentially, what Struct class does.)

-- Matma Rex

···

2012/2/20 Ralph Shnelvar <ralphs@dos32.com>:

What I want to do is not change the interface but the implementation. That is, I want to get a list of the names of the arguments by introspection.

Bartosz,

Monday, February 20, 2012, 10:19:41 AM, you wrote:

What I want to do is not change the interface but the implementation. That is, I want to get a list of the names of the arguments by introspection.

It is much simpler and IMO makes much more sense not to figure out
variable names while already having variables, but to figure out their
contents while having names. Like this:

class Class
  def attr_accessor_init *meths
    attr_accessor *meths
    define_method :initialize do |*args|
      meths.each_with_index do |m, i|
        self.send :"#{m}=", args[i]
      end
    end
  end
end

irb(main):013:0>> class A
irb(main):014:1>> attr_accessor_init :a, :b, :c
irb(main):015:1>> end

irb(main):029:0>> A.new 4, 6, 8
=>> #<A:0xd6cb18 @a=4, @b=6, @c=8>

(This is, essentially, what Struct class does.)

-- Matma Rex

This is an elegant solution.

Not quite what I wanted .... but I learned a lot from it.

Thank you.

···

2012/2/20 Ralph Shnelvar <ralphs@dos32.com>: