我正在学习Ruby并希望能够做到这一点:
Printer.hi there
并拥有Ruby输出
"hi there"
到目前为止,我有以下实现
class Printer
def method_missing(name, *args)
puts "#{name} #{args.join(',')}"
end
end
但这只能让我做到
Printer.hi "there"
如果我尝试
Printer.hi there
我得到了
NameError: undefined local variable or method `there' for main:Object
这是有道理的,因为我没有定义'那里'。有没有办法让这项工作?
答案 0 :(得分:3)
不,这是不可能以给定的形式(据我所知)。
你不是在寻找缺少方法的方法,你正在寻找Ruby解释器中的等价物来捕获它找不到给定的符号。所以虽然你不能在那里拦截它,但你可以在一个区块内进行:
def hi(&block)
begin
yield
rescue NameError => e
e.message =~ /variable or method `(.+)'/
puts "hi #{$1}"
end
end
hi { there } # => hi there
请注意,我觉得你是一个可怕的世界公民,向你展示这个。请不要在任何地方使用它。
答案 1 :(得分:0)
不,因为需要引用字符串,因此不会将它们视为变量。
否则there
之类的变量需要一些特殊的字符来表示它是一个字符串。然而,由于需要处理空间,因此仍然无法正常工作。
使用单引号或双引号 这就是语言的运作方式。接受这个并继续下一个挑战:)
答案 2 :(得分:0)
是的,有办法。当您在没有显式接收器的情况下编写there
时,接收器是该范围的self
对象。在这种情况下,它是main
。在methods_missing
上下文中定义main
。
def method_missing(name, *args)
puts "#{name} was called with arguments: #{args.join(',')}"
end
但是,如果你这样做,那可能会破坏你的其余代码。我认为没有意义这样做。
由于puts
的返回值为nil
,如果您Printer.hi there
,则评估为Printer.hi(nil)
。因此,为了输出"hi there"
,您需要定义:
class Printer
def self.hi _; puts "hi there" end
end
答案 3 :(得分:0)
有趣的是,您可以使用以下代码在ruby 1.8.7中执行此操作:
def method_missing(*args)
puts args.join ' '
end
我从Gary Bernhardt的演讲中了解到了这一点Wat。在1.9中,这会给你一个堆栈级别太深的错误,除非你在一个类中执行它。谷歌引导我访问Aurthur's tech blog thing上的这篇帖子,声称你可以在JRuby 1.9模式下做类似的事情:
def method_missing(*args)
puts [method.to_s, args].flatten.join ' '
end
然而,当我在MRI 1.9.3上尝试这个时,它也没有用。所以在1.9你不能完全做你想要的。这是我能来的最接近的地方:
class Printer
def self.hi(message)
puts "hi #{message}"
end
def self.method_missing(m, *args)
[m.to_s, args].flatten.join ' '
end
def self.bare
hi there
end
end
Printer.bare