Module_functions are private?

I have a piece of code that does something like this:

module M
def foo; end
module_function :foo
end

class Foo
include M
end

Foo.new.foo()

and was very surprised to discover that it doesn’t work:

NameError: private method `foo’ called for #Foo:0x402db40c
from (irb):10

Why does module_function() make foo() private?

Paul

Why does module_function() make foo() private?

Perhaps to use it like this

pigeon% ruby -e 'p Math.sin(0)'
0.0
pigeon%

pigeon% ruby -e 'include Math; p sin(0)'
0.0
pigeon%

Guy Decoux

Making it private doesn’t help there; it still works if it is public:

irb(main):001:0> module Math
irb(main):002:1> public :sin
irb(main):003:1> end
=> Math
irb(main):004:0> include Math
=> Object
irb(main):005:0> Math.sin(0)
=> 0.0
irb(main):006:0> sin(0)
=> 0.0

Paul

···

On Mon, Apr 21, 2003 at 11:23:54PM +0900, ts wrote:

Why does module_function() make foo() private?

Perhaps to use it like this

pigeon% ruby -e ‘p Math.sin(0)’
0.0

pigeon% ruby -e ‘include Math; p sin(0)’
0.0

irb(main):006:0> sin(0)
=> 0.0

pigeon% ruby -e 'module Math public :sin end; include Math; p self.sin(0)'
0.0
pigeon%

In your example, you use it like a private method

Guy Decoux

Making it private doesn’t help there; it still works if it is public:

···

----- Original Message -----
From: “Paul Brannan” pbrannan@atdesk.com


You’re assuming that public is the default, as with a normal method
definition. Perhaps, in this case, the default was “as limited as
possible”, so they made it private because in the cases shown (the most
common cases) private worked just fine.

Out of curiosity, what is it you are trying to do? Why does it need to be a
module function?

Chris

I understand that. I was pointing out that the example you gave me did
not answer my original question (which is why module_function changes
the access at all).

Paul

···

On Tue, Apr 22, 2003 at 12:14:45AM +0900, ts wrote:

irb(main):006:0> sin(0)
=> 0.0

pigeon% ruby -e ‘module Math public :sin end; include Math; p self.sin(0)’
0.0
pigeon%

In your example, you use it like a private method

I have a function that I want to use as if it were a normal public
instance method, but I don’t always want to create an instance in order
to use the method. I thought module_function was the right way to do
this. But when I write:

module Foo
public
def f1; end
def f2; end
module_function :f2
def f3; end
private
def f4; end
end

It makes sense that f4 is private, but it is not clear why f2 is
private.

The workaround is obvious; I’m just interested in the reasoning behind
module_function()'s behavior.

Paul

···

On Tue, Apr 22, 2003 at 12:15:15AM +0900, Chris Pine wrote:

Out of curiosity, what is it you are trying to do? Why does it need to be a
module function?

Paul Brannan wrote:

I have a function that I want to use as if it were a normal public
instance method, but I don’t always want to create an instance in order
to use the method. I thought module_function was the right way to do
this. But when I write:

module Foo
public
def f1; end
def f2; end
module_function :f2
def f3; end
private
def f4; end
end

It makes sense that f4 is private, but it is not clear why f2 is
private.

The workaround is obvious; I’m just interested in the reasoning behind
module_function()'s behavior.

I’m gonna try to read Matz’ mind for a second. :slight_smile:

When you call module_function, you end up with two methods: Foo#f2 and
Foo.f2

Now, imagine the brain wracking as you try to debug someone who mixes
Foo#f2 calls with Foo.f2 calls (or Bar.f2 calls from a class Bar that
includes Foo). Why is this brainwracking? Well, remember those pesky
instance variables? Foo.f2 uses Foos instance variables, but Foo#f2
would mess with whatever object it is included into. Now go ahead and
use class variables and try to figure out what is going on when you mix
the modes of calling the method. (Go on, I dare ya!)

So it seems the semantics are way different, and since it appears one
is using module_function as merely a neater way of writing def self.f2;
end, making Foo#f2 private protects you from shooting yourself in the
foot…

… while allowing you to blow it to bits with a public :f2 if you
absolutely want to. Enjoy the ECT while at the looney bin, if you choose
that path. 8-(

···


([ Kent Dahl ]/)_ ~ [ http://www.stud.ntnu.no/~kentda/ ]/~
))_student
/(( _d L b_/ NTNU - graduate engineering - 5. year )
( __õ|õ// ) )Industrial economics and technological management(
_
/ö____/ (_engineering.discipline=Computer::Technology)

I understand that. I was pointing out that the example you gave me did
not answer my original question (which is why module_function changes
the access at all).

When you write

pigeon% ruby -e 'module Math public :sin end; include Math; p 1.sin(0)'
0.0
pigeon%

What do ruby ?

Do it send the message :sin to `1' ? In this case what is the argument
given to this method ?

Do it call the method Math#sin ? In this case the only possible receiver
is Math.

#sin is a numeric method or a math function ?

Guy Decoux

This makes sense, thanks.

Paul

···

On Tue, Apr 22, 2003 at 06:03:48PM +0900, ts wrote:

pigeon% ruby -e ‘module Math public :sin end; include Math; p 1.sin(0)’
0.0
pigeon%

What do ruby ?

Do it send the message :sin to `1’ ? In this case what is the argument
given to this method ?

Do it call the method Math#sin ? In this case the only possible receiver
is Math.

#sin is a numeric method or a math function ?

http://www.bayarea.com/mld/mercurynews/news/5676110.htm