Robert Klemme
10/4/2004 8:43:00 AM
"Giulio Piancastelli" <giulio.piancastelli@gmail.com> schrieb im
Newsbeitrag news:1096822941.974872.80190@h37g2000oda.googlegroups.com...
> Hi all,
>
> Visibility issues within a module are not entirely clear to me. I was
> writing a little Ruby module in the process of learning the language,
> but found myself facing with a behaviour I considered quite strange.
> The guts of my problem is summarized by the following case study:
>
> module A1
> def f; puts 'A1::f'; end
> module_function :f
> end
>
> module A2
> def f; g; end;
> def g; puts 'g'; end
> module_function :f
> end
>
> module A3
> def f; g; end;
> private
> def A3.g; puts 'A3.g'; end
> module_function :f
> end
>
> Now, if I call A1::f, I get 'A1::f' printed on output, and that's OK.
> Problems arise whenever I call A2::f and A3.g! The call to A2::f fails
> because a NameError is raised, telling me about an undefined local
> variable or method g for A2 module, which, ahem, it seems to me it's
> plain false, since a g function is definetely defined in module A2.
g is defined as an *instance method* in A2, but not as a module singleton
method. By doing module_function :f in A2 you do basically the same as
"def A2.f() ...", i.e. you define a method of the instance A2. f tries to
invoke self.g while self is the module instance. But since you did not do
"def A2.g..." or "module_function g:" it's not there.
> The
> call to A3.g, then, prints 'A3.g' on output, but that should not happen
> because I defined that function to be private in the module.
Well, the private relates to instance methods defined thereafter, but "def
A3.g ..." defines a method of the instance A3, i.e. not instances of A3
but the module itself. If you want to make it private you can do this:
module A3
class <<self
private
def g; puts 'A3.g'; end
end
end
>> A3.g
NoMethodError: private method `g' called for A3:Module
from (irb):9
>> A3.instance_eval { g }
A3.g
=> nil
> So, what's really happening? I'm puzzled!
Hope I could clear the fog a bit.
Regards
robert