【问题标题】:Monkey patching Fixnum and Bignum without duplication猴子修补 Fixnum 和 Bignum 没有重复
【发布时间】:2015-04-01 21:28:12
【问题描述】:

我添加了两个处理数字的小助手,但我发现我必须复制粘贴我的方法才能使其同时适用于 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

【问题讨论】:

  • 享受欧拉计划的乐趣。 ;)

标签: ruby monkeypatching


【解决方案1】:

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

整数

这个类是两个包含整数的具体类的基础,BignumFixnum

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 

你可以使用集合交集找到两者的共同类和模块:

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

对于两个(或更多)类不共享适当的公共模块或类的情况,您可以选择这样做:

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 }

【讨论】:

  • 如果最常见的祖先不是类怎么办? (例如Array.ancestors & Range.ancestors -> Enumerable
  • @Caridorc 你可以使用Array.ancestors.grep(Class) 来选择课程
猜你喜欢
  • 2019-03-29
  • 1970-01-01
  • 2015-03-23
  • 2012-03-13
  • 2013-12-26
  • 2012-06-14
  • 2012-03-29
  • 2016-10-30
  • 1970-01-01
相关资源
最近更新 更多