受到运行时编辑源代码的一些lisp魔力的启发,
我想用红宝石做。看起来我无法从方法/类中获取源代码, 有办法吗?
我在这里写了一个示例源代码:
def helloworld n
"hello #{n}"
end
o = Kernel.method :helloword
Kernel.define_singleton_method o.name do |n|
eval o.source_code.sub('hello', 'hello world')
end
helloworld 'halida' #=> 'hello world halida'
答案 0 :(得分:0)
您无法获取代码的一部分的字符串表示,编辑它并期望Ruby重新评估您的更改。实现所需功能的唯一方法是使用ParseTree
获取源代码的s表达式,编辑并使用{{1}}生成一串ruby代码。他们将Ruby2Ruby
和def ...
添加到字符串中并使用它调用eval。
在现实世界中,它太难以且容易出错。但我不知道其他任何方式。
注意:ParseTree仅适用于Ruby 1.8。
答案 1 :(得分:0)
看一下method_source gem。它由pry REPL用于show-method
命令。
看起来这个gem使用标准Method#source_location
(在Ruby 1.9中可用)来定位方法并获取其源代码。显然,它不适用于动态定义的方法和C方法。有关详细信息,请参阅文档。
答案 2 :(得分:0)
您可以轻松地获取Ruby中方法的源代码。
想象一下以下假设课程:
class Klass
def self.foo
:foo
end
def bar
:bar
end
end
如您所见,此类有两种方法:
使用.method
和.instance_method
以编程方式访问它们:
m1 = Klass.method :foo
=> #<Method: Klass.foo>
m2 = Klass.instance_method :bar
=> #<UnboundMethod: Klass#bar>
您可以使用.source
方法查看其源代码:
puts m1.source
def self.foo
:foo
end
=> nil
puts m2.source
def self.bar
:bar
end
=> nil
因为Ruby有开放类和动态加载,你也可以添加或 在运行时更改方法。只需重新打开课程并重新定义方法:
Klass.foo
=> :foo
class Klass
def self.foo
:foobar
end
end
Klass.foo
=> :footer
以前在课程中定义的其他方法将不受影响:
Klass.bar
=> :bar
警告:在运行时重新定义类行为(也称为“Monkey Patching”) 是一个非常强大的工具,它也可能有点危险。当前版本的Ruby 支持一种更加可控的方式来实现这种称为“改进”的方法。