元编程:输出方法主体为文本 [英] Meta-programming: output method body as text

查看:82
本文介绍了元编程:输出方法主体为文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在模块中动态定义一个方法,我想检查一下将方法绑定到类实例后,该方法的主体是否符合我的期望.有没有办法输出(作为文本形式)方法主体?

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#nameMethod#arityMethod#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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆