Выполнение Ruby-скрипта в модуле - PullRequest
2 голосов
/ 13 января 2010

Почему происходит следующее:

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 ]

6 голосов
/ 13 января 2010

Использование ранее неиспользованного имени может очистить вашу путаницу:

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
4 голосов
/ 13 января 2010

Я думаю, что определение должно быть:

def Test.test
    puts "test"
end
2 голосов
/ 13 января 2010
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
1 голос
/ 13 января 2010

test не вызывает метод, который вы определили: он вызывает Kernel.test, который ожидает 2 аргумента - таким образом, исключение ArgumentError.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...