Hi,
I just discovered a behavior of ruby that seems strange to me.
I have a module containing classes, and i'd like those classes to be
able to call some method of the module, so i tried different solutions :
module Foo
def self.bar
puts "bar!"
end
bar # works
class Baz
# bar # doesn't work
# self.bar # doesn't work
Foo.bar # need to know the module name
end
end
I'd like to be able to call the method from Foo::Baz without knowing the
name of the module, but the only way i found is to call Foo.bar from
inside Baz.
Now if you replace "module Foo end" by "Module.new.module_eval {}"...
Shouldn't ruby walk the nesting stack when it doesn't find a method name ?
Is this going to change in 2.0 ?
Cheers,
Yoann
Hi --
Hi,
I just discovered a behavior of ruby that seems strange to me.
I have a module containing classes, and i'd like those classes to be
able to call some method of the module, so i tried different solutions :
module Foo
def self.bar
puts "bar!"
end
bar # works
class Baz
# bar # doesn't work
# self.bar # doesn't work
Foo.bar # need to know the module name
end
end
I'd like to be able to call the method from Foo::Baz without knowing the
name of the module, but the only way i found is to call Foo.bar from
inside Baz.
Now if you replace "module Foo end" by "Module.new.module_eval {}"...
Shouldn't ruby walk the nesting stack when it doesn't find a method name ?
No; it should walk the method lookup path. Inside Baz, self is Baz,
and there's no bar method defined in Baz's class (which is Class), nor
in Baz's singleton class, nor in any module mixed into either of
those. So Baz does not respond to "bar".
Is this going to change in 2.0 ?
I don't think it would make sense. Method-calling is determined by
the method lookup path of the receiver.
David
···
On Wed, 19 Apr 2006, Yoann Guillot wrote:
--
David A. Black (dblack@wobblini.net)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)
"Ruby for Rails" PDF now on sale! Ruby for Rails
Paper version coming in early May!
class Baz
FooMod = Foo
...
FooMod.bar
end
Now you only have to change it in one place at least
···
On Apr 18, 2006, at 9:44 PM, Yoann Guillot wrote:
module Foo
def self.bar
puts "bar!"
end
bar # works
class Baz
# bar # doesn't work
# self.bar # doesn't work
Foo.bar # need to know the module name
end
end
I'd like to be able to call the method from Foo::Baz without knowing the
name of the module, but the only way i found is to call Foo.bar from
inside Baz.
No. But there's a simple cure (that we might even suggest to go into
the std lib):
class Module
def outer
name.split('::')[0..-2].inject(::Object){|cl,n| cl.const_get n}
end
end
Now you can do
module Foo
def self.yeah; puts "yeah!" end
class Bar
p outer
outer.yeah
class Baz
p outer
end
end
end
p outer
and get
Foo
yeah!
Foo::Bar
Object
Kind regards
robert
···
2006/4/19, Yoann Guillot <john-rubytalk@ofjj.net>:
Hi,
I just discovered a behavior of ruby that seems strange to me.
I have a module containing classes, and i'd like those classes to be
able to call some method of the module, so i tried different solutions :
module Foo
def self.bar
puts "bar!"
end
bar # works
class Baz
# bar # doesn't work
# self.bar # doesn't work
Foo.bar # need to know the module name
end
end
I'd like to be able to call the method from Foo::Baz without knowing the
name of the module, but the only way i found is to call Foo.bar from
inside Baz.
Now if you replace "module Foo end" by "Module.new.module_eval {}"...
Shouldn't ruby walk the nesting stack when it doesn't find a method name ?
Is this going to change in 2.0 ?
--
Have a look: Robert K. | Flickr
Hi --
Hi,
I just discovered a behavior of ruby that seems strange to me.
Me too.
Shouldn't ruby walk the nesting stack when it doesn't find a method name ?
No; it should walk the method lookup path.
Fine. Why doesn't the method lookup path include the scope of the progenitor, or provide access to it? Your answer merely begs the question.
Yoann, I ran into the same rather exasperating behavior. Here's how I solved it:
module Foo
def self.bar
puts "bar!"
end
bar # works
class Baz
def initialize(parent)
@parentClass = parent
end
def something
# bar # doesn't work
# self.bar # doesn't work
Foo.bar # need to know the module name
@parentClass.bar # works, doesn't need module name hard-coded.
end
end
my_baz = Baz.new(self)
my_baz.something # no error
end
···
On Apr 18, 2006, at 18:50, dblack@wobblini.net wrote:
On Wed, 19 Apr 2006, Yoann Guillot wrote:
Pit Capitain wrote:
>module Foo
> def self.bar
> puts "bar!"
> end
>
> bar # works
>
> class Baz
> # bar # doesn't work
> # self.bar # doesn't work
> Foo.bar # need to know the module name
Module.nesting[ 1 ].bar
> end
>end
Thanks, Module.nesting[-2] is quite close of what i need.
However i does not work in
class Foo::Baz
end
In this case i can use Robert Klemme's Module.outer, but this one
doesn't work with anonymous modules
In my case i'll just use this workaround, but i still think that's odd.
I found something close that behaves like i though it would, it's
constants:
class Parent
PM = 'parent'
P = 'parent'
end
module Mod
PM = 'module'
M = 'module'
class Foo < Parent
puts M # => 'module'
puts P # => 'parent'
puts PM # => 'module'
end
end
where there is still the problem of
class Mod::Foo
puts M # NameError: uninitialized constant
end
Why is there a difference in the lookup path for constants Vs methods ?
Yoann