thanks!
one more question.
what is the “self” between “class << self;” and “end.clas_eval…”
good for???
it does not work without it, but I do not understand how
this works.
I like to create methods for my class dynamically based on
strings I pass to initialize
class Cl
def initialize(name)
class << self;self;end.class_eval {attr_accessor name}
end
end
what is the “self” between “class << self;” and “end.clas_eval…”
good for???
just a wild guess by a newbie:
“class<<self; def …; end” would perform the method def of the
class of the object in question (and it would add a method to it).
(This is probably not exactly true, since “def” probably isn’t real
method, but it wouldn’t matter at the moment.)
So between “class<<self” and “end” you speak to the sigleton class of
the object (and perhaps you create it if it doesn’t exist yet).
Thus “class<<self;self;end” tells the singleton class to return itself.
HTH,
Stepan
···
On Mon, 03 Jun 2002 14:26:54 +0200, Markus Jais mjais@web.de wrote:
I personally prefer the non-eval way that Guy Decoux recommend of using
type.send. Try and not use eval whenever you can IMO - plus I think the
clarity is enhanced in many non-eval solutions.
irb(main):019:0> class A
irb(main):020:1> def initialize(name)
irb(main):021:2> @name = name
irb(main):022:2> type.send(:attr_accessor, “name”)
irb(main):023:2> end
irb(main):024:1> end
nil
irb(main):025:0> a = A.new(‘billy’)
#<A:0x404f4318 @name=“billy”>
irb(main):026:0> a.name
“billy”
irb(main):027:0> a.name = ‘Freddy’
“Freddy”
irb(main):028:0> a.inspect
“#<A:0x404f4318 @name="Freddy">”
···
On Tue, 04 Jun 2002 02:58, you wrote:
thanks for your tip.
does one of the two possible solutions have any significant
advantages over the other or is this just a matter of style??
is one more like “the ruby way” ??
markus
Yukihiro Matsumoto wrote:
Hi,
In message “dynamic attr_accessor??” > > > > on 02/06/03, Markus Jais mjais@web.de writes:
I like to create methods for my class dynamically based on
strings I pass to initialize
a) attr_accessor is a method of a class
b) attr_accessor takes names of accessors
c) attr_accessor just defines two methods
So the answer should be
easier one:
class Cl
def initialize(name) @name = name
self.instance_eval "
def #{name}; @#{name}; end
def #{name}=(val); @#{name}=val; end
"
end
end
trickier one:
class Cl
def initialize(name) @name = name
class <<self
self
end.module_eval{attr_accessor name}
end
end
At Mon, 3 Jun 2002 22:38:04 +0900, Stepan Kasal wrote:
“class<<self; def …; end” would perform the method def of the
class of the object in question (and it would add a method to it).
(This is probably not exactly true, since “def” probably isn’t real
method, but it wouldn’t matter at the moment.)
So between “class<<self” and “end” you speak to the sigleton class of
the object (and perhaps you create it if it doesn’t exist yet).
Thus “class<<self;self;end” tells the singleton class to return itself.
That’s right, thank you.
And a singleton method of the object is defined in the
singleton class context by class_eval.
I personally prefer the non-eval way that Guy Decoux recommend of using
type.send. Try and not use eval whenever you can IMO - plus I think
the
clarity is enhanced in many non-eval solutions.
The ``type’’ solution defines new A instances methods wether you use
class_eval or send -
irb(main):019:0> class A
irb(main):020:1> def initialize(name)
irb(main):021:2> @name = name
irb(main):022:2> type.send(:attr_accessor, “name”)
class << self; self end.send(:attr_accessor, name)
:> Thus “class<<self;self;end” tells the singleton class to return itself.
:
:That’s right, thank you.
:
:And a singleton method of the object is defined in the
:singleton class context by class_eval.
“class<<self;self;end” is equivalent to “self.type”.
And “self.type” is equivalent to “type”.
class Cl
def initialize(name)
type.class_eval {attr_accessor, name}
end
end