如果我理解正确,您希望能够在传递给另一个方法的代码块中定义一个方法,但拦截该内部方法定义,以便它实际上没有被定义,而是转换为 S 表达式?所以你希望它的行为几乎就像它被注释掉并且一些外部过程已经通过源代码并将实现解析成一个 S 表达式?
就像是:
myMethod do
somemethod x
someother y
# def name(a,b)
# a+b
# end
end
where somemethod
and someother
still execute, 的实现name
被定义,但被 Ruby 解释器忽略。然后,您想以某种方式将此实现捕获为 S 表达式。通过将其注释掉,显然不会这样做,但它是我描绘行为的好方法。
好吧,RubyParser gem 可能会做你想做的事。它利用了将“here document”作为字符串传递给方法的能力,如下例所示:
def x (str)
str
end
x( <<-EOF )
this is
a here
document
EOF
# => "this is\n a here\ndocument\n"
使用 RubyParser,您可以执行以下操作:
require 'ruby_parser'
require 'pp'
pp RubyParser.new.parse( <<-EOF )
def plus(x,y)
x+y
end
EOF
# => s(:defn, :name, s(:args, :a, :b), s(:call, s(:lvar, :a), :+, s(:lvar, :b)))
那么,将它与您想要的代码合并将是一件小事,如下所示:
require 'ruby_parser'
def myMethod
x = yield
end
def somemethod( x )
puts x
end
def someother( y )
puts y
end
x = 'magic'
y = 'output'
sexp = myMethod do
somemethod x
someother y
RubyParser.new.parse( <<-EOF )
def name(a,b)
a+b
end
EOF
end
pp sexp
name(1,2)
# magic
# output
# s(:defn, :name, s(:args, :a, :b), s(:call, s(:lvar, :a), :+, s(:lvar, :b)))
# NoMethodError: undefined local variable or method 'name' for main:Object
如您所见,方法定义本质上只是一个字符串,并且可以这样操作。