У меня есть два предложения для вас, они не очень идеальны, но это лучшее, что я могу придумать.
Сначала вы можете определить новый метод в классе 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
, я просто выбрал его, так как он соответствует * 1013 Range* method.
Edit: У меня есть еще один для вас, просто потому, что я нахожу эту проблему настолько интересной.: P Это будет работать только в самой последней версии Ruby 1.9, но позволит использовать следующий синтаксис:
(0.exclude..10).include? 0 #=> false
(0.exclude..10).include? 0.00001 #=> true
Он использует ту же идею, что и мое второе предложение, но сохраняет маркер исключения вчисло вместо диапазона.Для этого мне нужно использовать SimpleDelegator в Ruby 1.9 (сами по себе числа не могут иметь переменных экземпляра или чего-либо еще), поэтому он не будет работать в более ранних версиях 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