Tôi có hai đề xuất cho bạn, chúng không lý tưởng lắm nhưng chúng là điều tốt nhất tôi có thể nghĩ đến.
Trước tiên, bạn có thể xác định một phương pháp mới trên lớp Phạm vi làm những gì bạn mô tả. Nó sẽ giống như thế này:
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
Tôi không biết, tôi vừa sử dụng từ đồng nghĩa "bao gồm" làm tên phương thức, có thể bạn có thể nghĩ về điều gì đó tốt hơn. Nhưng đó là ý tưởng.
Và sau đó bạn có thể làm điều gì đó phức tạp hơn và xác định phương thức trên lớp Phạm vi đánh dấu phạm vi là một phạm vi bạn muốn loại trừ giá trị bắt đầu và sau đó thay đổi phương thức include?
của Phạm vi để kiểm tra nhãn đó.
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
Một lần nữa, bạn có thể muốn có một tốt hơn (thêm thanh lịch?) Tên cho phương pháp hơn exclude_begin
, tôi chỉ chọn đó vì nó phù hợp với phương pháp Phạm vi của exclude_end?
.
Chỉnh sửa: Tôi có một số khác cho bạn, chỉ vì tôi thấy vấn đề này thật thú vị. : P này sẽ chỉ làm việc trong phiên bản mới nhất của Ruby 1.9, nhưng sẽ cho phép cú pháp sau:
(0.exclude..10).include? 0 #=> false
(0.exclude..10).include? 0.00001 #=> true
Nó sử dụng các ý tưởng tương tự như đề nghị thứ 2 của tôi, nhưng các cửa hàng "trừ điểm đánh dấu" trong số thay vì phạm vi. Tôi phải sử dụng SimpleDelegator của Ruby 1.9 để thực hiện điều này (số riêng của chúng không thể có các biến mẫu hoặc bất kỳ thứ gì), đó là lý do tại sao nó không hoạt động trong các phiên bản trước của 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
Tôi cho rằng việc loại trừ giá trị cuối cùng thường khá hữu ích như 'range = 0 ... something.size' Usecase của bạn cần loại trừ giá trị _first_ là gì? –
Tôi kiểm tra xem một tập hợp các giá trị nhất định có nằm trong phạm vi đó hay không. Tôi chỉ muốn xử lý các giá trị 0 khác nhau. Tôi biết làm thế nào để đạt được điều này, nhưng tôi đã tò mò, nếu có cái gì đó tương tự như '...' để loại trừ * đầu tiên * giá trị của một phạm vi. –
Tôi đã học được nhiều hơn về phạm vi trong 5 phút so với năm ngoái. Cảm ơn! –