2011-02-04 68 views
2

如何限制属于新类< Fixnum的变量,介于0到255之间? 或者如果我不能在Fixnim的子类中创建限制如何编写我自己的类限制?如何限制红宝石变量?

+0

通过编写自己的类 – 2011-02-04 18:46:49

+2

子类Fixnum对象不推荐,请参阅:http://stackoverflow.com/questions/1095789/sub-classing-fixnum-in-ruby – tokland 2011-02-04 18:49:57

回答

2

编写一个非继承类并使用method_missing来调用实例变量中的所有函数,它们限制返回值。

class MyNum 
    instance_methods.each {|m| eval("undef " << m) } 
    def initialize(fixnum) 
    @num = fixnum 
    end 
    def method_missing(name, *args, &blk) 
    ret = @num.__send__(name, *args, &blk) 
    Numeric === ret ? MyNum.new([[ret, 0].max, 255].min) : ret 
    rescue NoMethodError 
    super 
    end 
    def inspect 
    "MyNum(#{@num.inspect})" 
    end 
    def class 
    MyNum 
    end 
end 

int = MyNum.new(50) # => MyNum(50) 
int += 52 # => MyNum(102) 
int.sucC# => MyNum(103) 
int + 300 # => MyNum(255) 
int = -int # => MyNum(0) 
int.zero? # => true 
int == 0 # => true 
4
  1. 不要让一类的数量,使访问该号码通过setter方法的限制,类的一部分。
  2. 在你的类中,除了通过setter方法之外,不会设置实例变量。
  3. 如果你需要经常做这个,做一个辅助方法吧:

    class Module 
        def limited_value(name, range=0..100) 
        attr_reader name 
        define_method(:"#{name}=") do |new_value| 
         if range.include?(new_value) 
         instance_variable_set :"@#{name}", new_value 
         else 
         raise "Out of Bounds" 
         end 
        end 
        end 
    end 
    
    class Foo 
        limited_value :bar, 0..255 
    end 
    
    f = Foo.new 
    p f.bar  #=> nil 
    f.bar = 10 
    p f.bar  #=> 10 
    f.bar = 300 
    #=> tmp.rb:8:in `block in limited_value': Out of Bounds (RuntimeError) 
    

你可以或者选择将其值设置为最近的限制反而提高了运行时错误的。