我正在动态定义一个模块中的方法,并且我想检查一旦该方法绑定到一个类实例,该方法的主体就是我所期望的。有没有办法输出(作为文本)方法的主体?
模块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>
因此,我希望在应用于VendorOrdersController
时看到mixin的实现
为方便起见,可能是通过script/console
。
更新:Per @~ /我将字符串保存到变量puts
'。这非常有效。这揭示了我的代码中的错误(我想首先看到代码的原因)。下面的代码要好得多,并按预期工作。
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
答案 0 :(得分:5)
不,你无法获得方法背后的源代码。
您可以做的最好的事情是使用Method
获取代表该方法的Object#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
答案 1 :(得分:2)
确保您获得预期输出的最佳方法是编写测试。
另外 - 我不赞成像这样使用instance_eval。如果你必须使用这样的元编程,使用define_method
,或者你可以通过从路径传递一个参数而不做任何操作就可以逃脱,当然,这是一个更多的打字,但是那么多的元编程只是icky。 / p>
答案 2 :(得分:2)
在instance_eval运行之前,是否无法将字符串分配给变量并将其输出到控制台?
由于您的字符串定义了整个方法,因此您基本上已经拥有了源代码。
答案 3 :(得分:0)