简体   繁体   English

在Rails中为基本的ruby类添加方法

[英]Adding methods to base ruby class in rails

I have a very simple module, Utility , defined in utility.rb in the lib directory of a rails app. 我有一个非常简单的模块Utility ,在rails应用的lib目录中的utility.rb中定义。 It just adds two simple methods to classes from Ruby standard library. 它只是向Ruby标准库中的类添加了两个简单的方法。

However, when I require this file, the classes inside it don't respond to the methods I have defined here. 但是,当我require此文件时,其中的类不会响应我在此处定义的方法。 Such as, [].concat_with fails with a NoMethodError . 例如, [].concat_with失败,并显示NoMethodError Why? 为什么?

module Utility

  #
  # This module just contains useful functions
  #

  class Array
    def concat_with(seperator = "")
      reject! { |c| c.empty? }.join(seperator)
    end
  end

  class Float
    def flat
      "%gx" % (self / 100.00)
    end
  end

end

That's because you've defined new classes, instead of patching existing ones. 那是因为您定义了新类,而不是修补现有类。 These classes are Utility::Array and Utility::Float . 这些类是Utility::ArrayUtility::Float In module -clause everything is in the module's scope. module子句中,所有内容都在模块的范围内。

In Ruby 2.0 refinements were added that allow for temporary patches to existing classes, which seems like your case: 在Ruby 2.0中,添加了一些改进 ,以允许对现有类进行临时修补,这看起来像您的情况:

module Utility

  #
  # This module just contains useful functions
  #

  refine Array do
    def concat_with(seperator = "")
      reject! { |c| c.empty? }.join(seperator)
    end
  end

  refine Float do
    def flat
      "%gx" % (self / 100.00)
    end
  end

end

Then you do: 然后,您执行以下操作:

using Utility # Obviously, it has to be `required`
puts 3.14.flat

And these methods will only exist in the current scope. 这些方法仅存在于当前范围内。 Once you go outside, they will vanish. 一旦您走出去,它们就会消失。

Of course, you can reference classes from outside the module, like so: 当然,您可以从模块外部引用类,如下所示:

module Utility

  #
  # This module just contains useful functions
  #

  class ::Array
    def concat_with(seperator = "")
      reject! { |c| c.empty? }.join(seperator)
    end
  end

  class ::Float
    def flat
      "%gx" % (self / 100.00)
    end
  end

end

But that would write the changes permanently (process-wise). 但这将永久地(在过程方面)写入更改。 Sometimes that might be desirable, but I avoid this unless absolutely necessary, as it can easily conflict with changes made by other libraries. 有时这可能是合乎需要的,但除非绝对必要,否则我会避免这样做,因为它很容易与其他库所做的更改冲突。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM