红宝石-Rails:我无法在/ lib中的模块中调用函数-我在做什么错?

我知道我在做一些愚蠢的事情或没有做一些聪明的事情-我经常对两者都感到内gui。

这是一个使我痛苦的例子:

我在/ lib中将模块保存为test_functions.rb,如下所示

module TestFunctions
  def abc
    puts 123
  end
end

进入ruby脚本/运行器,我可以看到该模块正在自动加载(优于配置和其他所有约定)。

>> TestFunctions.instance_methods
=> ["abc"]

因此该方法是已知的,让我们尝试调用它

>> TestFunctions.abc
NoMethodError: undefined method `abc' for TestFunctions:Module from (irb):3

不。 这个怎么样?

>> TestFunctions::abc
NoMethodError: undefined method `abc' for TestFunctions:Module from (irb):4

测试再没有。

defined?(TestFunctions::abc) #=> nil, but
TestFunctions.method_defined? :abc #=> true

就像我在顶部说的那样,我知道我很蠢,有人可以让我哑巴吗?

Mike Woodhouse asked 2020-07-30T19:20:51Z
8个解决方案
59 votes

如果要使用Module级别的功能,请通过以下任意一种方式定义它们:

module Foo
  def self.method_one
  end

  def Foo.method_two
  end

  class << self
    def method_three
    end
  end
end

所有这些方式将使方法可作为Moduleinclude等使用

正如其他人所提到的,在Modules中的实例方法是在您拥有included Module的地方可用的方法。

Gareth answered 2020-07-30T19:21:15Z
26 votes

我将尝试自己总结各种答案,因为每个答案都有很有价值的说法,但是我现在还没有真正意识到最好的答案:

我问错了问题,因为做错了。

由于我无法解释的原因,我想要一个库中的一组完全独立的函数,这些函数代表了我试图从类中干燥的方法。 使用类似的方法可以实现

module Foo
  def self.method_one
  end

  def Foo.method_two
  end

  class << self
    def method_three
    end
  end

  def method_four
  end

  module_function :method_four
end

我也可以将include我的模块放在一个类中,在这种情况下,这些方法将成为该类的一部分,或者在外部,则将它们定义在我正在内部运行的任何类上(对象,内核或Irb,如果我是 互动吗?那么可能不是一个好主意)

关键是,没有充分的理由不让一堂课成为第一堂课-我莫名其妙地想到了一条思路,使我走下了一条很少使用且坦率的,有点古怪的分支。 可能是回溯到OO成为主流之前的日子(我的年龄已经足够大,直到今天我已经花了很多年编写程序代码)。

因此,这些函数已移入一个类,它们看起来很高兴,并且在需要时会欣然使用这样公开的类方法。

Mike Woodhouse answered 2020-07-30T19:21:58Z
24 votes

您也可以像这样使用module_function:

module TestFunctions
  def abc
    puts 123
  end

  module_function :abc
end

TestFunctions.abc  # => 123

现在,您可以在类中包括TestFunctions,并在TestFunctions模块中调用“ abc”。

Marcin Urbanski answered 2020-07-30T19:22:23Z
6 votes

我把这个弄乱了一段时间,学到了一些东西。 希望这可以帮助其他人。 我正在运行Rails 3.2.8。

我的模块(utilities.rb)如下所示,位于我的rails应用程序的/ lib目录中:

module Utilities

  def compute_hello(input_string)
     return "Hello #{input_string}"
  end

end

我的测试(my_test.rb)如下所示,位于我的rails应用程序的/ test / unit目录中:

require "test_helper"
require "utilities"

class MyTest < ActiveSupport::TestCase
  include Utilities

  def test_compute_hello
    x = compute_hello(input_string="Miles")
    print x
    assert x=="Hello Miles", "Incorrect Response"
  end

end

这里有一些注意事项:我的测试扩展了ActiveSupport :: TestCase。 这很重要,因为ActiveSupport将/ lib添加到$ LOAD_PATH。 ([请参见http://stackoverflow.com/questions/1073076/rails-lib-modules-and)]

其次,我既需要“需要”我的模块文件,也需要“包含”模块。 最后,重要的一点是要注意,从模块中包含的内容实际上已放入测试类中。 因此,请注意,您所包含的模块不要以“ test_”开头。 否则,Rails将尝试运行您的模块方法作为测试。

Miles Porter answered 2020-07-30T19:23:01Z
4 votes

您需要包括模块

include Testfunctions

然后,“ abc”将返回一些信息。

james answered 2020-07-30T19:23:25Z
4 votes

您不能直接在模块中调用方法。 您需要将其包括在课程中。 试试这个:

>> class MyTest
>>   include TestFunctions
>> end
=> MyTest
>> MyTest.new.abc
123
=> nil
Sarah Mei answered 2020-07-30T19:23:45Z
4 votes

您需要在函数前面加上模块名称,因为模块不是类:

您的/lib/test_functions.rb:

module TestFunctions
  def TestFunctions.abc
    puts 123
  end
end

您的代码使用模块方法:

require 'test_functions'
TestFunctions.abc
Douglas answered 2020-07-30T19:24:14Z
0 votes

今天,您可以使用module_function表示法进行操作。

module TestFunctions
  def abc
    puts 123
  end
end

现在module_function打印“ 123”

有关module_function的更多信息:[https://apidock.com/ruby/Module/module_function]

Rafael Gomes Francisco answered 2020-07-30T19:24:42Z
translate from https://stackoverflow.com:/questions/619840/rails-i-cant-call-a-function-in-a-module-in-lib-what-am-i-doing-wrong