提问人:Ben Garcia DB Solutions 提问时间:11/16/2023 最后编辑:Ben Garcia DB Solutions 更新时间:11/16/2023 访问量:32
Ruby- 跨模块的 NoMethodError
Ruby- NoMethodError across modules
问:
我在正确使用模块方面遇到了一些问题。
我有:
module Utilities
def file_search()
# some code
return x
end
end
module Remake_Components
require 'csv'
include Utilities
f = Utilities.file_search()
end
这给了我一个错误:我本来希望是运行该函数的结果。#<NoMethodError: undefined method "file_search" for Utilities:Module>
f
file_search
我的理解是我必须使用关键字才能使用其他方法中的函数,但似乎并非如此?include
答:
2赞
engineersmnky
11/16/2023
#1
我的理解是我必须使用 include 关键字才能使用其他方法中的函数,但似乎并非如此?
Module#include
将 Module 注入到 include 对象的分层链中,并使 included Module 的实例方法可供 include Object 的实例访问。
在你的例子中,定义了一个实例方法,通过调用,你已经使这个方法可用于的实例(但是,s没有实例(本身))。file_search
Utilities
include Utilities
Remake_Components
Module
您尝试将 Module 作为接收方调用的方式不需要调用,而是需要将方法定义为“类实例方法”或“模块函数”。file_search
Utilities
include
如果您希望它以这种方式工作,那么您有 2 个选择:
- 通过将方法声明更改为
Utilities
def self.file_search
- 使用方法(通常不是推荐的方法),例如
module_function
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)
其他一些不太重要的说明:
def file_search()
- 如果没有参数,可以省略括号,作为一般样式。return x
- Ruby 将始终返回最后一个表达式的值,因此除非您打算提前返回一个值,否则可以省略该值。return
module Remake_Components
- 虽然方法名称(和局部/实例变量)以 lower_snake_case 表示,但类和模块常量以 UpperCamelCase 表示,因此该模块通常以 UpperCamelCase 命名RemakeComponents
require 'csv'
- require 语句没有词法范围,因此它是否包含在模块声明中与它的可访问性无关。出于这个原因,require 调用(尤其是对核心库的调用)通常放在文件的顶部(在任何声明之外)。
评论