[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

safe array index ?

Christer Nilsson

1/11/2006 5:41:00 PM

Is it possible to catch index out of range ?

a = [1,2]

a[99] returns nil, I would like to get an error.

I've tried to define a SafeArray class, but failed.

I managed to redefine Array, but I want to have both possibilities.

class Array
alias old []
def [](index)
raise "index error" if index.abs >= self.size
self.old(index)
end
end

Is there something like Array.indexcheck = true ?

Christer

--
Posted via http://www.ruby-....


13 Answers

Edward Faulkner

1/11/2006 5:54:00 PM

0

On Thu, Jan 12, 2006 at 02:40:40AM +0900, Christer Nilsson wrote:
> Is it possible to catch index out of range ?
> I managed to redefine Array, but I want to have both possibilities.

You can use a delegator:

require 'delegate'

class SafeArray < DelegateClass(Array)
def [](index)
raise "index error" if index.abs >= size
super(index)
end
end

regards,
Ed

Florian Frank

1/11/2006 5:56:00 PM

0

Christer Nilsson wrote:

>Is it possible to catch index out of range ?
>
>a = [1,2]
>
>a[99] returns nil, I would like to get an error.
>
>I've tried to define a SafeArray class, but failed.
>
>I managed to redefine Array, but I want to have both possibilities.
>
>
a.fetch 99 # => raises IndexError: index 99 out of array

--
Florian Frank



Christer Nilsson

1/11/2006 6:16:00 PM

0

Ed and Florian, thank you both!

fetch() has the requested behaviour, but [] is nicer, syntactically.

a.fetch(2).fetch(3) # safe
a[2][3] # nice

with delegate I can have both!

class SafeArray < DelegateClass(Array)
def [](index)
fetch index
end
end

Christer

--
Posted via http://www.ruby-....


Christian Neukirchen

1/11/2006 7:33:00 PM

0

Edward Faulkner <ef@alum.mit.edu> writes:

> On Thu, Jan 12, 2006 at 02:40:40AM +0900, Christer Nilsson wrote:
>> Is it possible to catch index out of range ?
>> I managed to redefine Array, but I want to have both possibilities.
>
> You can use a delegator:
>
> require 'delegate'
>
> class SafeArray < DelegateClass(Array)
> def [](index)
> raise "index error" if index.abs >= size
> super(index)
> end
> end

Why do you use a delegator and don't just directly inherit from Array?

> regards,
> Ed
--
Christian Neukirchen <chneukirchen@gmail.com> http://chneuk...


Gavin Kistner

1/11/2006 8:00:00 PM

0

Christer Nilsson wrote:
> class SafeArray < DelegateClass(Array)
> def [](index)
> fetch index
> end
> end

Or, even easier:

class SafeArray < DelegateClass(Array)
alias_method :[], :fetch
end

David Vallner

1/11/2006 8:11:00 PM

0

Phrogz wrote:

>Christer Nilsson wrote:
>
>
>>class SafeArray < DelegateClass(Array)
>> def [](index)
>> fetch index
>> end
>>end
>>
>>
>
>Or, even easier:
>
>class SafeArray < DelegateClass(Array)
> alias_method :[], :fetch
>end
>
>
Groan at the different argument order of the alias statement and
#alias_method.




Christer Nilsson

1/11/2006 11:12:00 PM

0

Christian Neukirchen wrote:
> Why do you use a delegator and don't just directly inherit from Array?

I tried your suggestion, and it seems to work perfect as well.
Can't get simpler than this, I guess:

class SafeArray < Array
alias_method :[], :fetch
end

My original inheritance used @arr=Array.new and that was a dead end.


--
Posted via http://www.ruby-....


Robert Klemme

1/12/2006 11:07:00 AM

0

David Vallner wrote:
> Phrogz wrote:
>
>> Christer Nilsson wrote:
>>
>>
>>> class SafeArray < DelegateClass(Array)
>>> def [](index)
>>> fetch index
>>> end
>>> end
>>>
>>>
>>
>> Or, even easier:
>>
>> class SafeArray < DelegateClass(Array)
>> alias_method :[], :fetch
>> end
>>
>>
> Groan at the different argument order of the alias statement and
> #alias_method.

>> class Foo
>> def bar() "bar" end
>> alias :b :bar
>> end
=> nil
>> Foo.new.b
=> "bar"
>> class Bar
>> def foo() "foo" end
>> alias_method :f, :foo
>> end
=> Bar
>> Bar.new.f
=> "foo"

It seems to me order is the same: first the new name then the old name.
Am I missing something here?

Kind regards

robert

David Vallner

1/12/2006 11:36:00 AM

0

On Thu, 12 Jan 2006 12:08:05 +0100, Robert Klemme <bob.news@gmx.net> wrote:

> David Vallner wrote:
>> Phrogz wrote:
>>
>>> Christer Nilsson wrote:
>>>
>>>
>>>> class SafeArray < DelegateClass(Array)
>>>> def [](index)
>>>> fetch index
>>>> end
>>>> end
>>>>
>>>>
>>>
>>> Or, even easier:
>>>
>>> class SafeArray < DelegateClass(Array)
>>> alias_method :[], :fetch
>>> end
>>>
>>>
>> Groan at the different argument order of the alias statement and
>> #alias_method.
>
>>> class Foo
>>> def bar() "bar" end
>>> alias :b :bar
>>> end
> => nil
>>> Foo.new.b
> => "bar"
>>> class Bar
>>> def foo() "foo" end
>>> alias_method :f, :foo
>>> end
> => Bar
>>> Bar.new.f
> => "foo"
>
> It seems to me order is the same: first the new name then the old name.
> Am I missing something here?
>
> Kind regards
>
> robert
>
>


My bad. However, it seems alias_method silently lets me use an undefined
method name as the old name, which got me confused:

irb(main):001:0> class Foo
irb(main):002:1> def bar
irb(main):003:2> puts "BAR"
irb(main):004:2> end
irb(main):005:1> alias :bar :bar1
irb(main):006:1> alias_method :bar, :bar2
irb(main):007:1> end
NameError: undefined method `bar1' for class `Foo'
from (irb):5
irb(main):008:0> Foo.new.bar
BAR
=> nil
irb(main):009:0> Foo.new.bar1
NoMethodError: undefined method `bar1' for #<Foo:0x10295848>
from (irb):9
irb(main):010:0> Foo.new.bar2
NoMethodError: undefined method `bar2' for #<Foo:0x102934f0>
from (irb):10

David Vallner


Pit Capitain

1/12/2006 2:10:00 PM

0

David Vallner schrieb:
> My bad. However, it seems alias_method silently lets me use an
> undefined method name as the old name, which got me confused:
>
> irb(main):001:0> class Foo
> irb(main):002:1> def bar
> irb(main):003:2> puts "BAR"
> irb(main):004:2> end
> irb(main):005:1> alias :bar :bar1
> irb(main):006:1> alias_method :bar, :bar2
> irb(main):007:1> end
> NameError: undefined method `bar1' for class `Foo'
> from (irb):5

After the error on line 5, line 6 isn't executed anymore. Switch lines 5
and 6 and you see what I mean.

Regards,
Pit