有没有办法定义一个可以强制转换为String或Fixnum或Float的对象?这适用于收集值并使用它们评估一组受限制的简单表达式的系统。
我试过了:
class EmptyValue < Numeric
def to_s; ''; end
def to_str; ''; end
def to_i; 0; end
def to_int; 0; end
def to_f; 0.0; end
end
但
失败了1 + e
TypeError: EmptyValue can't be coerced into Fixnum
答案 0 :(得分:1)
多一点戳,这适用于我的所有用例:
class EmptyValue < Numeric
def to_s; ''; end
def to_str; ''; end
def to_i; 0; end
def to_int; 0; end
def to_f; 0.0; end
def +(other)
case other
when String
to_s + other
when Fixnum
to_i + other
when Float
to_f + other
end
end
end
答案 1 :(得分:0)
这就是我很久以前所做的:
class NullObject
attr_reader :null_object_type, :recorded_messages
alias ρ recorded_messages
def initialize( type_of_null_object = nil )
@null_object_type = type_of_null_object
@recorded_messages = []
end
def null_object? null_type = nil
null_object_type == null_type
end
alias null? null_object?
def to_a; [] end
def to_s; "null #{null_object_type}".strip end
def to_f; 0.0 end
def to_i; 0 end
def present?; false end
def empty?; true end
def blank?; true end
def inspect
"NullObject #{null_object_type}".strip
end
def method_missing ß, *aj, &b # :nodoc:
@recorded_messages << [ ß, aj, b ]; self
end
def respond_to? ß, *aj, &b # :nodoc:
true
end
protected
def == other # :nodoc:
null_object_type == other.null_object_type
end
end # class NullObject
# Strong zero.
#
ZERO = NullObject.new
ZERO.instance_exec {
ɪ = self
singleton_class.class_exec do
define_method :zero do ɪ end
end
def * other; other.class.zero end
def / other
self unless other.zero?
raise ZeroDivisionError, "The divisor is zero! (#{other})"
end
def + other; other end
def - other; -other end
def coerce other
return other, other.class.zero
end
def zero?; true end
def to_s; "∅" end
def inspect; to_s end
def to_f; 0.0 end
def to_i; 0 end
def == other
z = begin
other.class.zero
rescue NoMethodError
return false
end
other == z
end
}
class << Numeric; def zero; 0.0 end end
class << Integer; def zero; 0 end end
class << Float; def zero; 0.0 end end
class << Rational; def zero; Rational 0, 1 end end
class << Complex; def zero; Complex 0, 0 end end
class << String; def zero; '' end end
class << Array; def zero; [] end end
class << Hash; def zero; {} end end
所以,现在你有了0 + ZERO #=> 0
。我称之为“强零”。但这是一个黑客。我有一种直觉,这不是一个好习惯。