我在模块中动态定义一个方法,我想检查一旦该方法绑定(bind)到一个类实例,该方法的主体是否就是我所期望的。有没有办法输出(作为文本)方法的主体?
模块controller_mixins.rb
:
module ControllerMixin
instance_eval "def search_by_vendor (*args) \n" \
" @#{self.class.name.sub(/Controller/, '').tableize} = #{self.class.name.sub(/Controller/, '')}.find_all_by_vendor_id(params[:vendor_id]) \n"\
"respond_to do |format| \n" \
" format.html { render :template=>'/#{self.class.name.sub(/Controller/, '').tableize}/index', :layout=>'vendor_info'} \n" \
" format.xml { render :xml => @#{self.class.name.sub(/Controller/, '').tableize} } \n" \
"end \n"\
"end \n"
end
混合类:
class VendorOrdersController < ApplicationController
# GET /vendor_orders
# GET /vendor_orders.xml
require 'controller_mixins'
include ControllerMixin
<rest of class>
所以我想看看 mixin 应用于 VendorOrdersController
时的实现
为方便起见,可能通过 script/console
。
更新:根据@~/,我将字符串保存到一个变量中并将其放入
。效果很好。这揭示了我的代码中的错误(我首先想查看代码的原因)。下面的代码要好得多,并且可以按预期工作。
module ControllerMixin
def self.included(mod)
method_body = "def search_by_vendor \n" \
" @#{mod.name.sub(/Controller/, '').tableize} = #{mod.name.sub(/Controller/, '')}.find_all_by_vendor_id(params[:vendor_id]) \n"\
"respond_to do |format| \n" \
" format.html { render :template=>'/#{mod.name.sub(/Controller/, '').tableize}/index', :layout=>'vendor_info'} \n" \
" format.xml { render :xml => @#{mod.name.sub(/Controller/, '').tableize} } \n" \
"end \n"\
"end \n"
puts method_body
mod.class_eval(method_body)
end
end
最佳答案
不,您无法获取方法背后的源代码。
您能做的最好的事情就是获取表示使用 Object#method
的方法的 Method
对象。例如:
m = VendorOrdersController.method(:search_by_vendor)
但是您会发现,除了Method#name
、Method#arity
、Method#source_location
等之外,没有太多其他内容。
然而,在您的情况下,为什么不在使用 instance_eval
之前简单地将字符串存储在变量中并打印出来?
无论如何,您的instance_eval
将在模块声明时执行。您可能希望将其包装在 included
回调中,以便在包含时执行。
module ControllerMixin
def self.included(mod)
mod.instance_eval([...])
end
end
关于ruby - 元编程 : output method body as text,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3220623/