Module_function :func vs. MyModule.func?

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 -- <dolgun@excite.com> wrote:

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

Logan Capaldo 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 9/9/07, 7stud -- <dolgun@excite.com> wrote:

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

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

···

from :0
------------------------------------------------------------------------
     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

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

···

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

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

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

3) 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?

···

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