Module_function :func vs. MyModule.func?

The following produce the same output:

module MyModule
def greet
puts “hello”
end

module_function :greet

end

MyModule.greet

#-----vs.-----------

module MyModule
def MyModule.greet
puts “hello”
end
end

MyModule.greet

What is module_function used for?

7stud – wrote:

The following produce the same output:

module MyModule
def greet
puts “hello”
end

module_function :greet

end

MyModule.greet

#-----vs.-----------

module MyModule
def MyModule.greet
puts “hello”
end
end

MyModule.greet

What is module_function used for?

Ahhh, is this it:

module MyModule
def greet
puts “hello”
end
end

module OtherModule
include MyModule

module_function :greet

end

OtherModule.greet

7stud – wrote:

module MyModule
def greet
puts “hello”
end
end

module OtherModule
include MyModule

module_function :greet

end

OtherModule.greet

On p. 355 of “Programming Ruby (2nd ed)”, there is the equivalent of
this example:

module MyModule
def greet
puts “hello”
end

module_function :greet

end

MyModule.greet

As far as I can tell, in that example the module_function has no purpose
since I could just as easily make this change:

module MyModule
def MyModule.greet
puts “hello”
end
end

MyModule.greet

Is there any reason to use module_function in that example?

On 9/9/07, 7stud – [email protected] wrote:

def greet


Posted via http://www.ruby-forum.com/.

I believe the primary different shows up when the module is included
in another class. Consider this little snippet:

module MyModule
def greet
puts “hello”
end

module_function :greet
end

class MyClass
include MyModule

def hello
greet
end
end

MyModule.greet
MyClass.new.hello

When this gets run, the output will be:
hello
hello

The kicker is that greet is mixed into MyClass as a private method
(try calling MyClass.new.greet and watch the access error).

Using your explicit definition as such:

module MyExplicitModule
def MyExplicitModule.greet
puts “hello, explicitly!”
end
end

class MyExplicitClass
include MyExplicitModule

def hello
greet
end
end

MyExplicitModule.greet
MyExplicitClass.new.greet

The output of this code when run is
hello
module_function.rb:31:in hello': undefined local variable or method greet’ for #MyExplicitClass:0xb7cc7eac (NameError)
from module_function.rb:36

Essentially, by defining explicitly as MyExplicitModule.greet, the
method becomes a member of the module’s singleton class, and does not
get mixed into classes that include it. The module_function call
makes the method passed private and creates a singleton method.

You may also want to check out:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/17670

The poster gives a good example of the usage (Math.sqrt)

HTH

James Hunt wrote:

I believe the primary different shows up when the module is included
in another class.

Using your explicit definition as such:

module MyExplicitModule
def MyExplicitModule.greet
puts “hello, explicitly!”
end
end

class MyExplicitClass
include MyExplicitModule

def hello
greet
end
end

MyExplicitModule.greet
MyExplicitClass.new.greet

The output of this code when run is
hello
module_function.rb:31:in hello': undefined local variable or methodgreet’ for #MyExplicitClass:0xb7cc7eac (NameError)
from module_function.rb:36

Using your last example with module_function, I get the same result:

module MyModule
def greet
puts “hello”
end

module_function :greet

end

class MyClass
include MyModule
end

MyModule.greet
MyClass.new.greet

–output:–
hello
r1test.rb:13: private method `greet’ called for #MyClass:0x25490
(NoMethodError)

So, I’m not seeing any difference.

On Sep 8, 10:54 pm, 7stud – [email protected] wrote:

MyModule.greet

What is module_function used for?

Allow me to further confuse you:

module MyModule
extend self

  def greet
      puts "hello"
  end

end

MyModule.greet

Now I will explain. I the 1st case, using module_function makes an
actual copy of the instance method and defines it as a singleton
method of the module. In the 2nd case, you never have the instance
method to begin with, you simply defined the singleton method
directly. So to illustrate, the 1st example is equivalent to this:

module MyModule
def greet
puts “hello”
end

  def MyModule.greet
      puts "hello"
  end

end

Now for my last example. In which case, we defined the instance
method, but have also included the module into it’s own singleton
space. It is functionally the same as the 1st case but is also dynamic
–if we were to add a new method to MyModule later it would
automatically appear as a module method as well.

HTH,
T.

James Hunt wrote:

On 9/9/07, 7stud – [email protected] wrote:

class MyClass
(NoMethodError)

So, I’m not seeing any difference.

Posted via http://www.ruby-forum.com/.

If you look at my code, the MyClass definition creates an instance
method called hello that calls the private greet method. In the
Explicit example, greet just doesn’t exist in MyExplicitClass after
the mixin…

As far as I can tell, your private hello method is irrelevant since you
never call the hello method:

MyExplicitModule.greet
MyExplicitClass.new.greet

If I add the hello method to my last example that uses module_function,
I get the same output:

module MyModule
def greet
puts “hello”
end

module_function :greet

end

class MyClass
include MyModule

def hello
    greet
end

end

MyModule.greet
MyClass.new.greet

–output:–
hello
r1test.rb:18: private method `greet’ called for #MyClass:0x25350
(NoMethodError)

Trans wrote:

On Sep 8, 10:54 pm, 7stud – [email protected] wrote:

MyModule.greet

What is module_function used for?

Allow me to further confuse you:

Thanks for the response. Unfortunately, you’re speaking a language I
can’t understand yet. All I can do at this point is look at the output
and try to discern a difference.

On 9/9/07, 7stud – [email protected] wrote:

class MyClass
(NoMethodError)

So, I’m not seeing any difference.

Posted via http://www.ruby-forum.com/.

If you look at my code, the MyClass definition creates an instance
method called hello that calls the private greet method. In the
Explicit example, greet just doesn’t exist in MyExplicitClass after
the mixin…

On 9/9/07, 7stud – [email protected] wrote:

What is module_function used for?

module_function is used to help give us namespaces. The most visible
example is the Math module. Every method in there is
module_function’ed.

2 * Math.sin( 3.4 ) + Math.exp(24) # boy it sure is tiring typing
Math. all the time
include Math
2 * sin(3.4) + exp(24) # much better

On 9/9/07, 7stud – [email protected] wrote:

If you look at my code, the MyClass definition creates an instance
method called hello that calls the private greet method. In the
Explicit example, greet just doesn’t exist in MyExplicitClass after
the mixin…

As far as I can tell, your private hello method is irrelevant since you
never call the hello method:

If you look back at the original code posting, there were two test
sets: The first one (with MyModule) called MyClass.new.hello, whereas
the second one (with MyExplicitModule) called MyClass.new.greet.
Perhaps a bit confusing on my part - I apologize.

MyClass#hello was a public method calling MyClass#greet (a private
method) that was mixed in via the include of MyModule.

MyExplicitModule.greet
MyExplicitClass.new.greet
Again, this is the second test set, not the first. My apologies for
the confusion.

end
MyClass.new.greet

–output:–
hello
r1test.rb:18: private method `greet’ called for #MyClass:0x25350
(NoMethodError)

Because the last two lines should be:
MyModule.greet
MyClass.new.hello

That being said, I think Logan offered a much better explanation. +1
Logan

Logan C. wrote:

On 9/9/07, 7stud – [email protected] wrote:

What is module_function used for?

module_function is used to help give us namespaces. The most visible
example is the Math module. Every method in there is
module_function’ed.

2 * Math.sin( 3.4 ) + Math.exp(24) # boy it sure is tiring typing
Math. all the time
include Math
2 * sin(3.4) + exp(24) # much better

Ah hah! A difference I can discern:

module MyModule
def MyModule.greet
puts “hello”
end
end

MyModule.greet
#boy it sure is tiring typing MyModule every time I want to say hello

include MyModule
greet

–output:–
hello
r1test.rb:10: undefined local variable or method `greet’ for main:Object
(NameError)

On Behalf Of 7stud –

module MyModule

def MyModule.greet

puts “hello”

end

end

MyModule.greet

include MyModule

greet

–output:–

hello

r1test.rb:10: undefined local variable or method `greet’ for

main:Object (NameError)

ruby keeps it simpler.

botp@pc4all:~$ irb
irb(main):001:0> module MyModule
irb(main):002:1> def greet
irb(main):003:2> puts “hello”
irb(main):004:2> end
irb(main):005:1> module_function :greet
irb(main):006:1> end
=> MyModule
irb(main):007:0> MyModule.greet
hello
=> nil
irb(main):008:0> greet
NameError: undefined local variable or method `greet’ for main:Object
from (irb):8
from :0
irb(main):009:0> include MyModule
=> Object
irb(main):010:0> greet
hello
=> nil
irb(main):011:0> public_methods.grep /greet/
=> []
irb(main):012:0> private_methods.grep /greet/
=> [“greet”]

ok, namespacewise and ease of invocation, they behave like “fxns”
indeed. fair enough.

now, consider further,

irb(main):013:0> module MyModule
irb(main):014:1> def greet
irb(main):015:2> puts “Aloha”
irb(main):016:2> end
irb(main):017:1> end
=> nil
irb(main):018:0> MyModule.greet
hello
=> nil
irb(main):019:0> greet
Aloha
=> nil

Ah, another advantage: they allow for easy/independent modification,
saving the original.

irb(main):020:0> private_methods.grep /greet/
=> []
irb(main):021:0> public_methods.grep /greet/
=> [“greet”]
irb(main):022:0> system “qri module_function | head”
------------------------------------------------- Module#module_function
module_function(symbol, …) => self

 Creates module functions for the named methods. These functions
 may be called with the module as a receiver, and also become
 available as instance methods to classes that mix in the module.
 Module functions are copies of the original, and so may be changed
 independently. The instance-method versions are made private. If
 used with no arguments, subsequently defined methods become module
 functions.

=> true

kind regards -botp

On Behalf Of 7stud --:

1) When the Test module isn’t included in order to avoid

potential name

clashes of Test’s methods with other methods having the same

name, being

able to call all the methods using the syntax: Test.name.

2) When the Test module is included in order to avoid having

to to type

the module name in front of the method names and name clashes

aren’t a

concern, being able to call all the methods using the syntax: name.

do not forget third use of module_function since it’s one of the nifty
features…

  1. being able to change the module methods (or module “functions” so to
    speak) independently of the original methods. Remember, module functions
    are copies of the original,

ergo you can just modify the copies…

irb(main):050:0> module Test
irb(main):051:1> def show
irb(main):052:2> puts “This is a new show”
irb(main):053:2> end
irb(main):054:1> def f
irb(main):055:2> puts “This is a new goodbye”
irb(main):056:2> end
irb(main):057:1> end
=> nil

let’s test the original first…

irb(main):058:0> Test.show
testing
=> nil
irb(main):059:0> Test.f
goodbye
=> nil

ok, no change in original
now, see the change of the copy…

irb(main):060:0> show
This is a new show
=> nil
irb(main):061:0> f
This is a new goodbye
=> nil

kind regards -botp

Peña, Botp wrote:

do not forget third use of module_function since it’s one of the nifty
features…

  1. being able to change the module methods (or module “functions” so to
    speak) independently of the original methods. Remember, module functions
    are copies of the original,

ergo you can just modify the copies…

A new twist! I’ll quote your original example:

(I guess I won’t–it’s too long)

How does that work? You add a new instance method with the same name
as an existing instance method to the module, and somehow the new
instance method
overwrites the old one, and the old instance method gets promoted to a
“class” method?

Thanks for all the help. Here is a summary of the problem and solution:

module Test
def Test.show
puts “testing”
end

def f
    puts "goodbye"
end

end

Test.show #testing
Test.f #error

include Test

f #goodbye
show #error

As the example above shows, there is no way to achieve both of the
following:

  1. When the Test module isn’t included in order to avoid potential name
    clashes of Test’s methods with other methods having the same name, being
    able to call all the methods using the syntax: Test.name.

  2. When the Test module is included in order to avoid having to to type
    the module name in front of the method names and name clashes aren’t a
    concern, being able to call all the methods using the syntax: name.

module_function allows you to achieve both 1 and 2:

module Test
def show
puts “testing”
end
def f
puts “goodbye”
end

module_function :show, :f

end

Test.show #testing
Test.f #goodbye

include Test

show #testing
f #goodbye