ruby - 猴子修补 Fixnum 和 Bignum,无需重复

标签 ruby monkeypatching

我添加了两个小助手来处理数字,但我发现我必须复制粘贴我的方法才能使其与 BignumFixnum 一起使用。如何在没有这种复制粘贴的情况下为这两个数字类编写方法?

class Bignum
    def digits
        self.to_s.split('').map(&:to_i)
    end

    def palindrome?
        self.to_s == self.to_s.reverse
    end
end

class Fixnum
    def digits
        self.to_s.split('').map(&:to_i)
    end

    def palindrome?
        self.to_s == self.to_s.reverse
    end
end

最佳答案

这两个类都继承自 Integer 。如果你想同时影响两者,请使用 Monkeypatch。来自文档:

Integer

This class is the basis for the two concrete classes that hold whole numbers, Bignum and Fixnum.

2.0.0-p353 :001 > class Integer; def worked?; true; end; end
#=> nil 
2.0.0-p353 :002 > 42.worked?
#=> true 
2.0.0-p353 :003 > 42.class
#=> Fixnum 
2.0.0-p353 :004 > big = 2**90
#=> 1237940039285380274899124224 
2.0.0-p353 :005 > big.worked?
#=> true 
2.0.0-p353 :006 > big.class
#=> Bignum 

您可以使用集合交集找到两者的公共(public)类和模块:

Fixnum.ancestors & Bignum.ancestors
#=> [Integer, Numeric, Comparable, Object, Kernel, BasicObject] 

对于两个类(或更多)不共享适当的公共(public)模块或类的情况,您也可以执行以下操作:

module MyExtension
  def palindrome?
    ...
  end
end

class NumbaOne
  include MyExtension
end

class NumbaTwo
  include MyExtension
end

或者,如果您不想修改整个类,而只想修改某些实例:

a1 = NumbaOne.new
a2 = NumbaOne.new
b1 = NumbaTwo.new

[a1,a2,b1].each{ |o| o.extend MyExtension }

关于ruby - 猴子修补 Fixnum 和 Bignum,无需重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29401159/

相关文章:

ruby - Ruby 有关键字 `define` 吗?

c++ - 在循环中从 C++ 调用 Ruby 函数导致 "stack level too deep"

ruby-on-rails - 比较两个返回 bool 变量的 ActiveRecords 的每个值

ruby - MiniTest - 仅重新运行失败的测试

javascript - 是否可以重写 Javascript 数组或对象以使其可调用?

ruby - 在模块中打开类

jquery - 我可以替换或修改 jQuery UI 小部件上的函数吗?如何? (猴子补丁)

jquery - 在两个不同的部分 想传递两个变量

python - 在函数中模拟函数

sql-server - 向 activerecord-sqlserver-adapter 添加 SQL 2014 支持