模块中的Ruby脚本执行

时间:2010-01-13 18:08:22

标签: ruby

为什么以下失败?

module Test
    def test
        puts "test"
    end

    puts "testing"
    test
end

我得到了这个输出:

testing
test.rb:6:in `test': wrong number of arguments (ArgumentError)
    from test.rb:6:in `<module:Test>'
    from test.rb:1:in `<main>'

是不是因为模块尚未“编译”,因为尚未到达end关键字?

4 个答案:

答案 0 :(得分:6)

使用以前未使用的名称可能会让您感到困惑:

module Test
  def my_test
    puts "my_test"
  end
  puts "testing"
  my_test
end

结果

testing
NameError: undefined local variable or method `my_test' for Test:Module

module...end块内,当您调用my_test时,self(隐式接收器)是什么?它是模块Test。并且没有my_test“模块方法”。上面定义的my_test方法就像一个实例方法,发送到包含该模块的某个对象。

您需要将my_test定义为“模块方法”:

module Test
  def self.my_test
    puts "my_test"
  end
  puts "testing"
  my_test
end

结果

testing
my_test

如果您希望my_test作为实例方法,您想在模块定义中调用它:

method Test
  puts "testing"
  Object.new.extend(self).my_test
end

给出

testing
my_test

答案 1 :(得分:4)

我认为定义必须是:

def Test.test
    puts "test"
end

答案 2 :(得分:2)

module Test
  def test # This is an instance method
    puts "test"
  end

  puts "testing"
  test     # This is a call to a module method
end

这两个完全无关。在继承链中更高的位置,您有一个名为test的模块方法,它至少需要一个参数。 (我猜这是Kernel#test方法,它接受两个参数。)因为你将称为而没有一个参数,你会得到一个ArgumentError例外。

如果您要提供更多有关实际问题的详细信息,您正试图解决的问题,那么就可以提供更好的答案。在此之前,这里有几个想法:

将方法设为模块方法:

module Test
  def self.test; puts "test" end

  puts "testing"
  test
end

自己扩展模块:

module Test
  def test; puts "test" end

  extend self

  puts "testing"
  test
end

创建模块的实例:

module Test
  def test; puts "test" end
end

puts "testing"
Object.new.extend(Test).test

将模块混合到一个类中,并创建一个实例:

module Test
  def test; puts "test" end
end

class Foo; include Test end

puts "testing"
Foo.new.test

将模块混合到Module

module Test
  def test; puts "test" end
end

class Module; include Test end

module Test
  puts "testing"
  test
end

将模块混合到Object

module Test
  def test; puts "test" end
end

class Object; include Test end

puts "testing"
test

将模块混合到main对象中:

module Test
  def test; puts "test" end
end

include Test

puts "testing"
test

答案 3 :(得分:1)

test未调用您定义的方法:它正在调用Kernel.test,它需要2个参数 - 因此ArgumentError例外。