0

我正在学习 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

这是有道理的,因为我从未定义过“那里”。有没有办法使这项工作?

4

4 回答 4

3

不,这在给定的形式中是不可能的(据我所知)。

您不是在寻找缺少的方法,而是在 Ruby 解释器中寻找等价的方法,以便在找不到给定符号时进行捕获。所以虽然你不能在那里拦截它,但你可以在一个块内进行:

def hi(&block)
  begin
    yield
  rescue NameError => e
    e.message =~ /variable or method `(.+)'/
    puts "hi #{$1}"
  end
end

hi { there } # => hi there

请注意,向您展示这一点,我感觉自己是个糟糕的世界公民。请永远不要在任何地方使用它。

于 2013-05-04T01:48:33.110 回答
0

Interestingly you can do this in ruby 1.8.7 with just this code:

def method_missing(*args)
  puts args.join ' '
end

I learned about this from Gary Bernhardt's talk, Wat. In 1.9 this gives you a stack level too deep error unless you do it inside a class. Google lead me to this post on Aurthur's tech blog thing, which claims you can do something similar in JRuby 1.9 mode:

def method_missing(*args)
  puts [method.to_s, args].flatten.join ' '
end

However when I tried this on MRI 1.9.3 it did not work either. So in 1.9 you can't quite do what you want. Here is the closest I could come:

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
于 2013-05-04T07:56:56.350 回答
0

否,因为字符串需要被引用,所以它们不被视为变量。

否则,诸如此类的变量there将需要某种特殊类型的字符来指示它是一个字符串。然而,这仍然不能很好地工作,因为需要处理空间。

使用单引号或双引号。
这就是语言的运作方式。接受这个并继续下一个挑战:)

于 2013-05-03T17:37:56.187 回答
0

是的,有办法。当您在there没有显式接收器的情况下编写时,接收器是该self范围的对象。在这种情况下,它是mainmethods_missingmain上下文中定义。

def method_missing(name, *args)
  puts "#{name} was called with arguments: #{args.join(',')}"
end

但是,如果您这样做,那可能会弄乱您的其余代码。我认为这样做没有意义。

由于 is 的返回值putsnil如果你这样做Printer.hi there,它将评估为Printer.hi(nil)。所以为了让它输出"hi there",你需要定义:

class Printer
  def self.hi _; puts "hi there" end
end
于 2013-05-03T18:04:11.947 回答