Robert Klemme
5/6/2005 10:06:00 PM
"Logan Capaldo" <logancapaldo@gmail.com> schrieb im Newsbeitrag
news:4521f6680505061351685b2b5e@mail.gmail.com...
> On 5/5/05, Logan Capaldo <logancapaldo@gmail.com> wrote:
>> I was just wondering if maybe the range construction syntax could be
>> implemented as a set of operators?
>>
>> ie
>>
>> class Object
>> def ..(other)
>> Range.new(self, other)
>> end
>> def ...(other)
>> Range.new(self, other, true)
>> end
>> end
>>
>> This wouldn't implement the parser much (I don't think any way) and
>> it could be useful for things like
>> defining inifinite lazy lists, or other ranges with weird natures
>>
>> ie
>>
>> class InfRange
>> attr_reader :first
>> def take(n)
>> i = self.first
>> 1.upto(n) { yield(i); i = i.succ }
>> end
>> def initialize(n)
>> @first = n
>> end
>> end
>>
>> class Fixnum
>> def ..(other)
>> if other.nil?
>> InfRange.new(self)
>> else
>> Range.new(self, other)
>> end
>> end
>> def ...(other)
>> if other.nil?
>> InfRange.new(self)
>> else
>> Range.new(self, other, true)
>> end
>> end
>> end
>>
>> (1..inf).take(5) do |x|
>> p x
>> end
>>
>> Ok thats a pretty silly example, but lets say succ was more
>> complicated than just self + 1
>>
>> Eh maybe I'm crazy and this is useless. Just seems to be in line with
>> << and + etc. being changeable.
>>
>
> Nobody likes this idea? Or is it just so dumb its not worthy of a
> response? ;)
I didn't see you first posting - maybe it was lost somewhere along the way
and that's why nobody reacted.
First I thought, this is a good idea. Here are some caveats / remarks:
If you redefine Fixnum#... (assuming it was an ordinary operator) in order
to create a custom range with "1...3" then you will see a lot strange
behavior of existing code. In fact it might do more harm than good.
Ok, to avoid that, you would need to define YourSpecialClass#... - but if
you need a new class anyway, you can as well just define a new Range type
and use its constructor like "SpecialRange.new(1, 3)" or "SpecialRange[1,
3]". Or you define Array#to_special so you can do "for i in [1,
3].to_special". You can even define Range#to_special that does the job, so
you can do "for i in (1...3).to_special". All these are not much typing
overhead but show better that you're doing weired things...
As illustration:
class SomeRange
include Enumerable
def self.[](a,b) self.new a, b end
def initialize(a,b) @a, @b = a, b end
def each
i = @a
until i == @b
yield i
i = i.succ
end
self
end
end
>> for n in SomeRange.new(1, 3)
>> puts n
>> end
1
2
=> #<SomeRange:0x10188670 @b=3, @a=1>
>> for n in SomeRange[1, 3]
>> puts n
>> end
1
2
=> #<SomeRange:0x10183648 @b=3, @a=1>
>>
Not that bad, ain't it?
Kind regards
robert