【问题标题】:How does this deprecate method work?这种不推荐使用的方法是如何工作的?
【发布时间】:2010-11-04 14:33:23
【问题描述】:

我试图理解这个电话:

deprecate :new_record?, :new?

使用这种弃用方法:

   def deprecate(old_method, new_method)
      class_eval <<-RUBY, __FILE__, __LINE__ + 1
        def #{old_method}(*args, &block)
          warn "\#{self.class}##{old_method} is deprecated," + 
                "use \#{self.class}##{new_method} instead"
          send(#{new_method.inspect}, *args, &block)
        end
      RUBY
    end

我不太了解这里使用的元编程。但是,这只是别名 new_record? 方法的另一种方式 - 所以实际上,new_record? 仍然可用,但在您使用它时会发出警告?有人想解释一下这是如何工作的吗?

【问题讨论】:

    标签: ruby-on-rails ruby activerecord metaprogramming


    【解决方案1】:

    好的,所以这里发生的事情是程序员将 old_method 的所有功能都移到了 new_method 中。为了使两个名称都指向相同的功能但注意弃用,程序员放入deprecate 行。这会导致 http://en.wikipedia.org/wiki/Heredoc) 中指定的字符串在类级别被解释为代码(已评估)。字符串插值的工作方式与普通 ruby​​ 字符串一样。

    然后代码看起来像这样(如果我们要扩展元编程)

    class SomeClass
      def new?; true; end
    
      deprecate :new_record?, :new? # this generates the following code
    
      def new_record?(*args, &block)
        warn "SomeClass#new_record? is deprecated," + 
                "use SomeClass#new? instead"
        send(:new?, *args, &block)
      end
    end
    

    我希望这是有道理的

    【讨论】:

    • 好的,谢谢。这就说得通了。只有一件事我仍然不明白 - 这个语法:FILE, LINE + 1 如果“FILE, LINE + 1
    • 如果我将定义从 deprecate 更改为:“alias_method :new_record?, :new?”,除了不会收到警告之外,它是否会产生与上述相同的效果?
    • 据我所知,是的。 FILELINE 信息是 class_eval 的可选定位参数。如果它们丢失并且引发了异常,则回溯将包含类似(eval):3 new_record? 的内容。 FILE 是当前源文件,LINE 是当前行号,所以在失败的情况下,回溯将指向 eval 语句的定义位置。
    • 我认为heredoc ("
    • heredocs 在 ruby​​ 中有点有趣。他们实际上直到下一行才开始。你可以和他们一起做更有趣的事情log.gmarik.info/2007/12/rubys-here-document-heredoc-mini.html(最后一个例子)。
    猜你喜欢
    • 2014-10-11
    • 2017-12-23
    • 1970-01-01
    • 2010-10-12
    • 2023-03-29
    • 1970-01-01
    • 2022-08-08
    • 2023-03-31
    • 2014-05-05
    相关资源
    最近更新 更多