元编程:输出方法主体为文本 [英] Meta-programming: output method body as text
问题描述
我正在模块中动态定义一个方法,我想检查一下将方法绑定到类实例后,该方法的主体是否符合我的期望.有没有办法输出(作为文本形式)方法主体?
I'm dynamically defining a method in a module, and I'd like to check that once the method is bound to a class instance that the body of the method is what I'm expecting. Is there a way to output (as text) of the body of a method?
模块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
.
So I'd like to see the implementation of the mixin when applied to VendorOrdersController
probably via script/console
for convenience.
更新:每@〜//我将字符串保存到变量中,并puts
将其保存.那很好.这揭示了我的代码中的错误(我想首先查看代码的原因).下面的代码要好得多,并且可以按预期工作.
UPDATE: Per @~/ I saved the string to a variable and puts
'd it. That worked perfectly. Which brought to light an error in my code (the reason I wanted to see the code in the first place). Code below is much better, and works as expected.
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
推荐答案
不,您不能在方法后面获取源代码.
No, you cannot get the source code behind a method.
您能做的最好的就是得到Method
对象,该对象代表使用Object#method
的方法.例如:
The best you can do is get the Method
object that represents the method using Object#method
. For example:
m = VendorOrdersController.method(:search_by_vendor)
但是您会发现,除了Method#name
,Method#arity
,Method#source_location
等之外,其他内容都不多.
But you'll find that there's not much more than a Method#name
, Method#arity
, Method#source_location
, etc.
但是,就您而言,为什么不简单地将字符串存储在变量中,在使用instance_eval
之前将其打印出来呢?
In your case however, why not simply store the string in a variable, print it, before using instance_eval
?
无论如何,您的instance_eval
将在模块声明时执行.您可能希望将其包装在included
回调中,以便在包含时执行它.
Regardless, your instance_eval
will be executed at the moment of module declaration. You probably want to wrap it in an included
callback to have it executed at the moment of inclusion.
module ControllerMixin
def self.included(mod)
mod.instance_eval([...])
end
end
这篇关于元编程:输出方法主体为文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!