为何Ruby类外可调用lc方法,类内却提示未定义?
问题原因与解决办法
原因分析
Ruby的方法查找规则导致了这个差异:
- 顶级作用域中可调用的
lc方法,实际是定义在Object类中的私有实例方法。 - 在类外(main对象,属于
Object的实例)调用时,符合私有方法的调用规则——能在定义它的类的实例内部直接调用,所以正常执行。 - 但在
Translator类的实例方法translate里调用lc时,Ruby会优先在Translator实例自身、Translator类及其父类的公共/受保护方法中查找,Object的私有方法无法被子类实例直接调用,因此抛出NoMethodError。 - 尝试
::lc报错是因为::用于访问顶级常量或类/模块的方法,而lc是实例方法,并非常量或类方法,语法不合法。
解决办法
方法1:用send绕过私有方法限制
修改translate方法,通过send调用lc:
def translate text send(:lc, text, @to, @from) end
send方法可以无视方法的访问权限,直接调用目标方法。
方法2:找到lc所属模块并引入
如果能确定lc所属的模块(可以在类外执行p method(:lc).owner查看),在Translator类中引入该模块:
比如输出结果是LanguageConverter,则修改类:
require 'language_converter' class Translator include LanguageConverter # 引入模块 def initialize @to = 'ja'; @from = 'en'; end def translate text lc(text, @to,@from) end end
这样lc就会成为Translator实例的可用方法。
内容的提问来源于stack exchange,提问作者Caecilius-rgb
相关产品推荐
相关产品推荐

