[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Module visibility

Giulio Piancastelli

10/3/2004 5:02:00 PM

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. 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.

So, what's really happening? I'm puzzled!
Thanks in advance,
Giulio Piancastelli.

8 Answers

Mauricio Fernández

10/3/2004 6:04:00 PM

0

On Mon, Oct 04, 2004 at 02:04:55AM +0900, Giulio Piancastelli wrote:
> module A1
> def f; puts 'A1::f'; end
> module_function :f
> end
>
> module A2
> def f; g; end;
> def g; puts 'g'; end
^^^
def self.g or better module_function :g too

> module_function :f
> end
>
> module A3
> def f; g; end;
^^^
call with no explicit receiver, private methods work OK
> private
> def A3.g; puts 'A3.g'; end
> module_function :f
> end

--
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com



gabriele renzi

10/3/2004 6:35:00 PM

0

Mauricio Fernández ha scritto:

>>def g; puts 'g'; end
>
> ^^^
> def self.g or better module_function :g too

why better module_function ?

PS

giulio, your name sounds italian, if you are not aware of
the italian ruby user group you may like to visit
ada2.unipv.it/ruby and join the mailing list

Mauricio Fernández

10/3/2004 7:37:00 PM

0

On Mon, Oct 04, 2004 at 03:34:55AM +0900, gabriele renzi wrote:
> Mauricio Fernández ha scritto:
>
> >>def g; puts 'g'; end
> >
> > ^^^
> > def self.g or better module_function :g too
>
> why better module_function ?

so that
include A2
f

works

--
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com



Markus

10/3/2004 7:45:00 PM

0

On Sun, 2004-10-03 at 11:34, gabriele renzi wrote:
> Mauricio Fernández ha scritto:
>
> >>def g; puts 'g'; end
> >
> > ^^^
> > def self.g or better module_function :g too
>
> why better module_function ?

Why is it needed or why is module_function a better way to define it
than "def self."? I can answer the first: if you don't do one or the
other of them the module won't be able to see "g" (and thus f will fail
with a name error) since g will only be defined for instances of classes
that include the module.
As for the second, I'd have to guess that he was expressing a
stylist preference, but that is only a guess.

-- MarkusQ



Giulio Piancastelli

10/3/2004 8:52:00 PM

0

Mauricio Fernández wrote:

> > module A3
> > def f; g; end;
> ^^^
> call with no explicit receiver, private methods work OK

Yes, but the problem is that I was able to call A3.g from outside the
module even if it was declared private. Why is that happening? Private
symbols in a module are private in respect to... what?
Regards,
Giulio Piancastelli

Florian Gross

10/3/2004 9:11:00 PM

0

Giulio Piancastelli wrote:

> Yes, but the problem is that I was able to call A3.g from outside the
> module even if it was declared private. Why is that happening? Private
> symbols in a module are private in respect to... what?

Interesting -- this is another difference between module_function
without arguments and extend self:

module A3
extend self
def f; g; end
private
def g; "A3.g"; end
end

A3.g # raises NoMethodError: private method `g' called for A3:Module
A3.f # => "A3.g"

I think the behavior of extend self is more appropriate than the
module_function one.

> Regards,
> Giulio Piancastelli

More regards,
Florian Gross

T. Onoma

10/4/2004 5:43:00 AM

0

On Sunday 03 October 2004 05:14 pm, Florian Gross wrote:
> Giulio Piancastelli wrote:
> > Yes, but the problem is that I was able to call A3.g from outside the
> > module even if it was declared private. Why is that happening? Private
> > symbols in a module are private in respect to... what?
>
> Interesting -- this is another difference between module_function
> without arguments and extend self:
>
> module A3
> extend self
> def f; g; end
> private
> def g; "A3.g"; end
> end
>
> A3.g # raises NoMethodError: private method `g' called for A3:Module
> A3.f # => "A3.g"
>
> I think the behavior of extend self is more appropriate than the
> module_function one.

Talk about your Too Many Ways!

module X
extend self
private
# ...
end

module X
module_function
# ...
end

module X
class << self
def ameth
end
private
include self
end

module X
class << self
def ameth
end
private
def ameth
end

module X
def self.ameth
private
def ameth
end

module X
def X.ameth
private
def ameth
end

module X
def X.ameth
def ameth
priavte :ameth
end


T.



Robert Klemme

10/4/2004 8:43:00 AM

0


"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