Dear all,
I'd like to create methods similar to the attr_* way. I'd like to
write
class Foo
lookup_meth :bar, :baz
def some_other_methods
....
end
end
The lookup_meth should define for class Foo methods such as
def bar
# tricky lookup stuff
return value
end
def bar=(obj)
@bar=obj
end
How would I write such lookup_meth? I've been playing a bit with eval,
but I didn't get it quite right.
Patrick
class Object
def self.lookup_meth(*args)
args.each do | name |
eval %(
def #{name}
@#{name} ||= '24'
end
def #{name}=(arg)
@#{name} = arg
end
)
end
end
end
class Test
lookup_meth :test1, :test2
def testme
p self.test1
self.test1 = 42
p self.test1
end
end
Test.new.testme
=>
"24"
42
Hope that helps,
Brian
···
On 12/08/05, Patrick Gundlach <clr7.10.randomuser@spamgourmet.com> wrote:
Dear all,
I'd like to create methods similar to the attr_* way. I'd like to
write
class Foo
lookup_meth :bar, :baz
def some_other_methods
....
end
end
The lookup_meth should define for class Foo methods such as
def bar
# tricky lookup stuff
return value
end
def bar=(obj)
@bar=obj
end
How would I write such lookup_meth? I've been playing a bit with eval,
but I didn't get it quite right.
Patrick
--
http://ruby.brian-schroeder.de/
Stringed instrument chords: http://chordlist.brian-schroeder.de/
Hello Brian,
class Object
def self.lookup_meth(*args)
args.each do | name |
eval %(
def #{name}
@#{name} ||= '24'
end
def #{name}=(arg)
@#{name} = arg
end
)
end
end
end
class Test
lookup_meth :test1, :test2
def testme
p self.test1
self.test1 = 42
p self.test1
end
end
Test.new.testme
=>
"24"
42
Hope that helps,
Yes, it helps! But there are two more questions left: since this
lookup_meth is defined in Ojbect, it might get overridden by another
method definition of the same name, right? Is it possible to move this
definition somewhere 'closer' to my classes? And number two: I have
one variable that I need to check. Example:
def self.lookup_meth(*args)
args.each do | name |
eval %(
def #{name}
if @othervar # <-----------
puts "hello"
end
@#{name} ||= '24'
end
Any way to avoid a warning about 'instance variable @othervar not
initialized'?
Thanks so far,
Patrick
Hi --
Dear all,
I'd like to create methods similar to the attr_* way. I'd like to
write
class Foo
lookup_meth :bar, :baz
def some_other_methods
....
end
end
The lookup_meth should define for class Foo methods such as
def bar
# tricky lookup stuff
return value
end
def bar=(obj)
@bar=obj
end
How would I write such lookup_meth? I've been playing a bit with eval,
but I didn't get it quite right.
Patrick
class Object
def self.lookup_meth(*args)
args.each do | name |
eval %(
def #{name}
@#{name} ||= '24'
end
def #{name}=(arg)
@#{name} = arg
end
)
end
end
end
class Test
lookup_meth :test1, :test2
def testme
p self.test1
self.test1 = 42
p self.test1
end
end
Test.new.testme
=>
"24"
42
# However.....
p test1 => "24"
You've defined them as instance methods of Object, so they appear at
the top level.
You'd probably want:
class Module
def lookup_meth(*args)
args.each do |arg|
define_method(arg) do
instance_variable_get("@#{arg}")
end
define_method("#{arg}=") do |v|
instance_variable_set("@#{arg}", v)
end
end
end
end
or similar.
David
···
On Sat, 13 Aug 2005, [ISO-8859-1] Brian Schröder wrote:
On 12/08/05, Patrick Gundlach <clr7.10.randomuser@spamgourmet.com> wrote:
--
David A. Black
dblack@wobblini.net
[...]
Any way to avoid a warning about 'instance variable @othervar not
initialized'?
This warning doesn't show up in production code. Strange.... I'll
investigate.
Patrick
Hello David,
[...]
You'd probably want:
class Module
def lookup_meth(*args)
args.each do |arg|
define_method(arg) do
instance_variable_get("@#{arg}")
end
define_method("#{arg}=3D") do |v|
instance_variable_set("@#{arg}", v)
end
end
end
end
That's cool. Where does 'Module' come into play? What part of
class Foo ; end
is or is related to 'Module'? Hmm, I think I see: class is an instance
of Class, which is a subclass of Module, right? So the above with
class Class
def lookup_meth(*args)
args.each do |arg|
....
should do the same? But why is 'def' not a method of Class? Or would
be this too tricky to implement, so it is part of some other level of
parsing?
Patrick
You can move it as close as to the class itself. It's just a class
method. Or you could put it in a super-class and inherit from that.
class Test
def self.do_something(*args)
puts "doing something with #{args}"
end
end
class Test
do_something :foobar
end
Cheers,
Navin.
···
Patrick Gundlach <clr7.10.randomuser@spamgourmet.com> wrote:
Yes, it helps! But there are two more questions left: since this
lookup_meth is defined in Ojbect, it might get overridden by another
method definition of the same name, right? Is it possible to move this
definition somewhere 'closer' to my classes? And number two: I have
Patrick Gundlach asked:
... since this
lookup_meth is defined in Ojbect, it might get overridden by another
method definition of the same name, right? Is it possible to move this
definition somewhere 'closer' to my classes?
You can define your lookup_meth in the target class directly:
class Test
def self.lookup_meth(*args)
#...
end
lookup_meth :test1, :test2
end
Or you can define it in a module, and extend the classes you want to use it
in:
module LookupMeth
def lookup_meth(*args)
#... (no changes required here)
end
end
class Test
extend LookupMeth
lookup_meth :test1, :test2
end
And number two: I have
one variable that I need to check. Example:
def self.lookup_meth(*args)
args.each do | name |
eval %(
def #{name}
if @othervar # <-----------
puts "hello"
end
@#{name} ||= '24'
end
Any way to avoid a warning about 'instance variable @othervar not
initialized'?
You can initialize the variable the line before:
@othervar ||= nil
Or you can change your if condition:
if defined?(@otherbar) && @othervar
Cheers,
Dave
Patrick Gundlach wrote:
That's cool. Where does 'Module' come into play? What part of
class Foo ; end
is or is related to 'Module'? Hmm, I think I see: class is an instance
of Class, which is a subclass of Module, right?
That's right.
class Class
def lookup_meth(*args)
args.each do |arg|
....
should do the same?
For classes, yes. It would not work with modules, obviously.
But why is 'def' not a method of Class? Or would
be this too tricky to implement, so it is part of some other level of
parsing?
It wouldn't work to make def a method, because what goes after "def"
(e.g. "my_cool_method(something, something_else)") isn't a valid object
in Ruby. You can use Module#define_method if you want something similar.
I wrote earlier:
You can define your lookup_meth in the target class directly:
...
Or you can define it in a module, and extend the classes you want to use
it in:
I'd like to add that Dwemthy's Array does a similar kind of thing, and is an
interesting game, and you should have a read, and maybe try and get through
the Array.
http://poignantguide.net/dwemthy/
Here's a teaser:
class Dragon < Creature
life 1340 # tough scales
strength 451 # bristling veins
charisma 1020 # toothy smile
weapon 939 # fire breath
end
Cheers,
Dave
Hi Dave,
I'd like to add that Dwemthy's Array does a similar kind of thing, and is an
interesting game, and you should have a read, and maybe try and get through
the Array.
http://poignantguide.net/dwemthy/
Here's a teaser:
class Dragon < Creature
life 1340 # tough scales
strength 451 # bristling veins
charisma 1020 # toothy smile
weapon 939 # fire breath
end
Thats really neat. Thanks Why for this examples and for the pretty
nice guide.
Patrick