Ruby块使用method_missing

| 请注意,这是对我的问题的跟进。 我正在尝试解析以下Tcl代码:
foo bar {
  biz buzz
}
在Tcl中,
foo
是方法名称,
bar
是参数,其余的是要由
eval
处理的\“ block \”。 现在这是我当前的实现:
def self.foo(name, &block)
  puts \"Foo --> #{name}\"
  if block
    puts \"block exists\"
  else
    puts \"block does not exist\"
  end
end

def self.method_missing(meth, *args, &block)
  p meth
  p block
  meth.to_s &block
end

tcl = <<-TCL.gsub(/^\\s+/, \"\").chop
  foo bar {
    biz buzz
  }
TCL

instance_eval(tcl)
输出以下内容:
:bar
#<Proc:0x9e39c80@(eval):1>
Foo --> bar
block does not exist
在此示例中,当将该块传递给“ 1”方法时,该块不存在。但是在“ 7”中它确实存在(至少它似乎存在)。这里发生了什么? 请注意,我知道ruby的括号优先级,并意识到这项工作:
foo (bar) {
  biz buzz
}
但是,我想省略括号。那么在红宝石中(没有词法分析)这可能吗?     
已邀请:
您可以做(我标记了更改的行):
def self.foo args                  # changed
  name, block = *args              # changed
  puts \"Foo --> #{name}\"
  if block
    puts \"block exists\"
  else
    puts \"block does not exist\"
  end
end

def self.method_missing(meth, *args, &block)
  p meth
  p block
  return meth.to_s, block          # changed
end
这样,块将存在。     
这与ѭ7无关。在将block和一些参数一起传递时,您根本不能省略括号。在您的情况下,Ruby将尝试使用block作为参数调用
bar
方法,并且所有结果都将作为单个参数传递给
foo
方法。 您可以通过简化方法调用来自己尝试(所有元编程都掩盖了您所遇到的实际问题):
# make a method which would take anything
def a *args, &block
end

# try to call it both with argument and a block:
a 3 {
  4
}
#=>SyntaxError: (irb):16: syntax error, unexpected \'{\', expecting $end
#   from /usr/bin/irb:12:in `<main>\'
    
因此,我找到的最佳解决方案是在处理字符串之前仅对字符串
gsub
tcl = <<-TCL.gsub(/^\\s+/, \"\").chop.gsub(\'{\', \'do\').gsub(\'}\', \'end\')
  foo bar {
    biz buzz
  }
TCL
    

要回复问题请先登录注册