假设我的范围是0到10:
range = 0...10
三个点表示排除最后一个值(10):
range.include? 10
=> false
现在,是否有类似且优雅的方法来排除第一个值?
对于上面的示例,这意味着包含更大(>
,不 >=
)的所有值,而不是0和更小的值比10。
答案 0 :(得分:5)
我有两条建议给你,它们不是很理想,但它们是我能想到的最好的。
首先,您可以在Range类上定义一个执行所描述内容的新方法。它看起来像这样:
class Range
def have?(x)
if x == self.begin
false
else
include?(x)
end
end
end
p (0..10).have?(0) #=> false
p (0..10).have?(0.00001) #=> true
我不知道,我只是使用“include”的同义词作为方法名称,也许你可以想到更好的东西。但这就是想法。
然后你可以做一些更精细的事情,并在Range类上定义一个方法,将一个范围标记为要排除其开始值的范围,然后更改Range的include?
方法以检查那个标记。
class Range
def exclude_begin
@exclude_begin = true
self
end
alias_method :original_include?, :include?
def include?(x)
return false if x == self.begin && instance_variable_defined?(:@exclude_begin)
original_include?(x)
end
alias_method :===, :include?
alias_method :member?, :include?
end
p (0..10).include?(0) #=> true
p (0..10).include?(0.00001) #=> true
p (0..10).exclude_begin.include?(0) #=> false
p (0..10).exclude_begin.include?(0.00001) #=> true
同样,您可能希望方法的名称比exclude_begin
更好(更优雅?),我只是选择了它,因为它与Range的exclude_end?
方法一致。
编辑:我还有另外一个,因为我觉得这个问题很有趣。 :P这只适用于最新版本的Ruby 1.9,但允许使用以下语法:
(0.exclude..10).include? 0 #=> false
(0.exclude..10).include? 0.00001 #=> true
它使用与我的第二个建议相同的想法,但将“排除标记”存储在数字而不是范围中。我必须使用Ruby 1.9的SimpleDelegator来实现这一点(数字本身不能有实例变量或任何东西),这就是为什么它不适用于早期版本的Ruby。
require "delegate"
class Numeric
def exclude
o = SimpleDelegator.new(self)
def o.exclude_this?() true end
o
end
end
class Range
alias_method :original_include?, :include?
def include?(x)
return false if x == self.begin &&
self.begin.respond_to?(:exclude_this?) &&
self.begin.exclude_this?
original_include?(x)
end
alias_method :===, :include?
alias_method :member?, :include?
end
答案 1 :(得分:3)
没有
((0+1)..10)
答案 2 :(得分:0)
也许您可以创建自己的范围类型。
class FancyRange
def initialize(minimum, maximum, exclusive_minimum, exclusive_maximum)
# insert code here
end
# insert more code here
end