Forum: Ruby safe array index ?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Af95bdaf87958c40150b813e94381bfd?d=identicon&s=25 Christer Nilsson (christer)
on 2006-01-11 18:40
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
036a1b88dafaab8ffd73a8b0a74b5b38?d=identicon&s=25 Edward Faulkner (Guest)
on 2006-01-11 18:56
(Received via mailing list)
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
D84df7c68f790e492c4ad4ec5fe65547?d=identicon&s=25 Florian Frank (Guest)
on 2006-01-11 18:56
(Received via mailing list)
Christer Nilsson wrote:

>
a.fetch 99 # => raises IndexError: index 99 out of array
Af95bdaf87958c40150b813e94381bfd?d=identicon&s=25 Christer Nilsson (christer)
on 2006-01-11 19:15
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
7264fb16beeea92b89bb42023738259d?d=identicon&s=25 Christian Neukirchen (Guest)
on 2006-01-11 20:34
(Received via mailing list)
Edward Faulkner <ef@alum.mit.edu> writes:

>     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?
Ec9233451f7c6ba37a83388b87a1f565?d=identicon&s=25 Phrogz (Guest)
on 2006-01-11 21:05
(Received via mailing list)
Christer Nilsson wrote:
> class SafeArray < DelegateClass(Array)
>   def [](index)
>     fetch index
>   end
> end

Or, even easier:

class SafeArray < DelegateClass(Array)
  alias_method :[], :fetch
end
430ea1cba106cc65b7687d66e9df4f06?d=identicon&s=25 David Vallner (Guest)
on 2006-01-11 21:11
(Received via mailing list)
Phrogz wrote:

>
>Or, even easier:
>
>class SafeArray < DelegateClass(Array)
>  alias_method :[], :fetch
>end
>
>
Groan at the different argument order of the alias statement and
#alias_method.
Af95bdaf87958c40150b813e94381bfd?d=identicon&s=25 Christer Nilsson (christer)
on 2006-01-12 00:11
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.
5befe95e6648daec3dd5728cd36602d0?d=identicon&s=25 Robert Klemme (Guest)
on 2006-01-12 12:10
(Received via mailing list)
David Vallner wrote:
>>>
> #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
430ea1cba106cc65b7687d66e9df4f06?d=identicon&s=25 David Vallner (Guest)
on 2006-01-12 12:39
(Received via mailing list)
On Thu, 12 Jan 2006 12:08:05 +0100, Robert Klemme <bob.news@gmx.net>
wrote:

>>>> end
>> Groan at the different argument order of the alias statement and
>>> def foo() "foo" end
>
>     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
93d566cc26b230c553c197c4cd8ac6e4?d=identicon&s=25 Pit Capitain (Guest)
on 2006-01-12 15:10
(Received via mailing list)
David Vallner schrieb:
>   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
25e11a00a89683f7e01e425a1a6e305c?d=identicon&s=25 Wilson Bilkovich (Guest)
on 2006-01-12 15:53
(Received via mailing list)
On 1/11/06, Edward Faulkner <ef@alum.mit.edu> wrote:
>     raise "index error" if index.abs >= size
>     super(index)
>   end
> end
>

I've been trying to get my head around Delegator, but I'm not seeing
what it does here.
Subclassing Array seems to work the same way.

irb session:
irb(main):001:0> class SafeArray < Array
irb(main):002:1> def [](index)
irb(main):003:2> raise "Index error" if index.abs >= size
irb(main):004:2> super(index)
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> a = SafeArray.new
=> []
irb(main):008:0> a.concat [1,2,3,4,5]
=> [1, 2, 3, 4, 5]
irb(main):009:0> b = Array.new
=> []
irb(main):010:0> b.concat [1,2,3,4,5]
=> [1, 2, 3, 4, 5]
irb(main):011:0> a
=> [1, 2, 3, 4, 5]
irb(main):012:0> b
=> [1, 2, 3, 4, 5]
irb(main):013:0> a[9]
RuntimeError: Index error
        from (irb):3:in `[]'
        from (irb):13
irb(main):014:0> b[9]
=> nil
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2006-01-12 16:08
(Received via mailing list)
On Jan 12, 2006, at 8:51 AM, Wilson Bilkovich wrote:

> I've been trying to get my head around Delegator, but I'm not seeing
> what it does here.

One problem is that all the examples in this thread have been leaving
out the critical step, setting the object to delegate too in the
constructor.

Delegator is for passing calls on to *an object*.  See the sample
initialize() methods and documentation of DelegateClass() here:

http://www.ruby-doc.org/stdlib/libdoc/delegate/rdo...

Hope that helps.

James Edward Gray II
430ea1cba106cc65b7687d66e9df4f06?d=identicon&s=25 David Vallner (Guest)
on 2006-01-12 23:17
(Received via mailing list)
On Thu, 12 Jan 2006 15:10:18 +0100, Pit Capitain <pit@capitain.de>
wrote:

>>   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
>


<dense>
D'oh... Ah well, I'm deformed by JSP compilers slapping me left right
and
center at office it seems.
</dense>

Cheers.

David Vallner
This topic is locked and can not be replied to.