假设我的范围是0到10:
range = 0...10
Run Code Online (Sandbox Code Playgroud)
三个点表示排除最后一个值(10):
range.include? 10
=> false
Run Code Online (Sandbox Code Playgroud)
现在,有没有类似和优雅的方法来排除第一个值?
对于上面的例子,这将意味着以包括所有的值更大(>,不 >=)大于0且小于10.
不。
((0+1)..10)
Run Code Online (Sandbox Code Playgroud)
我有两个建议,他们不是很理想,但他们是我能想到的最好的.
首先,您可以在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
Run Code Online (Sandbox Code Playgroud)
我不知道,我只是使用"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
Run Code Online (Sandbox Code Playgroud)
同样,你可能想要一个更好(更优雅?)的方法名称exclude_begin,我只是选择它,因为它与Range的exclude_end?方法一致.
编辑:我有另一个给你,因为我发现这个问题很有趣.:P这只适用于最新版本的Ruby 1.9,但允许使用以下语法:
(0.exclude..10).include? 0 #=> false
(0.exclude..10).include? 0.00001 #=> true
Run Code Online (Sandbox Code Playgroud)
它使用与我的第二个建议相同的想法,但将"排除标记"存储在数字而不是范围中.我必须使用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
Run Code Online (Sandbox Code Playgroud)