Ruby- モジュール間で NoMethodError が発生する
概要
モジュールを正しく使用する方法を理解するのにいくつかの問題があります。
私は持っている:
module Utilities
def file_search()
# some code
return x
end
end
module Remake_Components
require 'csv'
include Utilities
f = Utilities.file_search()
end
これにより、次のエラーが発生します: #<NoMethodError: Utilities:Module の未定義メソッド “file_search”> 私は f が file_search 関数を実行した結果であると予想していました。
他のメソッドで関数を使用するには include キーワードを使用する必要があると理解していましたが、そうではないようです。
解決策
他のメソッドで関数を使用するには include キーワードを使用する必要があると理解していましたが、そうではないようです。
Module#include は、モジュールを包含オブジェクトの階層チェーンに挿入し、包含オブジェクトのインスタンスが包含モジュールのインスタンス メソッドにアクセスできるようにします。
あなたの場合、 file_search は Utilities で定義されたインスタンス メソッドであり、 include Utilities を呼び出すことで、このメソッドを Remake_Components のインスタンスで利用できるようにしました (ただし、モジュールには (それ自体) インスタンスがありません)。
ユーティリティモジュールをレシーバーとして使用して file_search を呼び出そうとしている方法では、インクルードの呼び出しは必要ありませんが、メソッドを「クラスインスタンスメソッド」または「モジュール関数」として定義する必要があります。
このように動作させたい場合は、2 つのオプションがあります。
module Utilities
def file_search
# some code
return x
end
module_function :file_search
end
どちらのオプションでも、Utilities.file_search を呼び出すことができます。ただし、後者では、Module#include を使用するときに、このメソッドをプライベート インスタンス メソッドとして「含める」こともできます。
例として:
module A
def self.foo = 'Foo'
def bar = 'Bar'
module_function :bar
end
class B
include A
def test_foo = A.foo
def test_bar = bar
end
A.foo
#=> "Foo"
A.bar
#=> "Bar"
B.new.test_foo
#=> "Foo"
B.new.test_bar
#=> "Bar"
B.new.foo
#=> undefined method `foo' for #<B:0x00007f0c7785e528> (NoMethodError)
B.new.bar
#=> private method `bar' called for #<B:0x00007ff5a5dbe5a0> (NoMethodError)
その他、それほど重要ではないメモをいくつか挙げておきます。