Ruby中的模块函数定义

时间:2013-03-02 14:57:52

标签: ruby

我正在使用版本1.9.3学习Ruby,继续学习LearnRubyTheHardWay的教程。

似乎在Module中定义函数时,必须在函数名前加上模块的名称,如下所示:

module MyStuff
    def MyStuff.apple()
        puts "I AM APPLES!"
    end
end

MyStuff.apple()

为什么你不能这样做:

module MyStuff
    def apple()
        puts "I AM APPLES!"
    end
end

MyStuff.apple() # this does not work

在Ruby文档中,有an example like the one above

我出错了什么?

4 个答案:

答案 0 :(得分:3)

模块是一种将方法,类和常量分组在一起的方法。模块为您带来两大好处: 模块提供命名空间并防止名称冲突。 模块实现了mixin工具。

取自(http://www.tutorialspoint.com/ruby/ruby_modules.htm

您可以改为:

module MyStuff
    def self.apple
        puts "I AM APPLES!"
    end
end

MyStuff.apple # "I AM APPLES!"

答案 1 :(得分:2)

在第一种情况下,您创建了一个类级方法,这意味着您可以直接在类/模块上调用它:MyStuff.apple。在第二个中,您创建了一个实例级方法,这意味着您需要一个实例来访问该方法:

class MyKlazz
    include MyStuff
end

obj=MyKlazz.new
obj.apple

答案 2 :(得分:1)

那是因为您在MyStuff上将apple定义为实例方法,并且由于MyStuff不是其自身的实例,因此您无法在其上调用apple。< / p>

要拨打apple,您可以选择以下几种方法:

  • 明确定义MyStuff上的方法,如您所见:

    module MyStuff
      def MyStuff.apple
        puts "I AM APPLES!"
      end
    end
    
    MyStuff.apple  #=> "I AM APPLES!"
    

    但您不必明确,并且可以使用self代替MyStuff

    module MyStuff
      def self.apple
        puts "I AM APPLES!"
      end
    end
    
    MyStuff.apple  #=> "I AM APPLES!"
    
  • 您可以include MyStuff进入一个类并在该类的实例上调用该方法:

    module MyStuff
      def apple
        puts "I AM APPLES!"
      end
    end
    
    class Foo; include MyStuff; end
    
    Foo.new.apple  #=> "I AM APPLES!"
    
  • 你可以extend MyStuff进入一个类或模块 - 这包括MyStuff本身:

    module MyStuff
      extend self
    
      def apple
        puts "I AM APPLES!"
      end
    end
    
    MyStuff.apple  #=> "I AM APPLES!"
    
    module OtherStuff; extend MyStuff; end
    
    OtherStuff.apple  #=> "I AM APPLES!"
    

这与课程的工作方式非常相似。例如,这不起作用:

class Foo
  def bar; 42; end
end

Foo.bar  #=> #<NoMethodError: undefined method `bar' for Foo:Class>

因为bar同样是一个实例方法,所以你需要创建一个实例或者使bar成为一个类方法:

class Foo
  def bar; 42; end
  def self.bar; 24; end
end

Foo.bar      #=> 24
Foo.new.bar  #=> 42

答案 3 :(得分:0)

第一个例子......

module MyStuff
  def MyStuff.apple()
    puts "I AM APPLES!"
  end
end

...之所以有效,是因为你在模块上定义了方法,而不是模块中的IN,这就是你在第二个例子中所做的:

module MyStuff
  def apple()
    puts "I AM APPLES!"
  end
end

如果你有一个班级并做同样的事情,那就类似了:

class Conrad
  def Conrad.apple()
    puts "I AM APPLES"
  end
end

您也可以使用def self.apple(),这意味着相同:

class Conrad
  def self.apple()
    puts "I AM APPLES"
  end
end

在这两种情况下,您都是在类本身上定义一个方法而不是该类的实例。

对于模块,如果扩展了该类(即Conrad.apple),那么您将定义一个可供类使用的方法,或者如果包含该类,则定义该类的实例(即{{1 }})。