ref: perl - 配列を1番目からはじめてみる
ref: 配列の先頭要素が「0番目」であることは気持ち悪いか…「N番目」という言葉を考察してみる - ’(rubikitch wanna be (a . lisper))
ref: JavascriptやPHPの配列や関数などで 配列の最初の要素が.. - 人力検索はてな
ruby も自由に設定できてしまいますね。
class Array alias aref_org [] def [](x) aref_org(x - 1) end end a = [:foo, :bar, :baz] p a[1] #=> :foo p a[2] #=> :bar p a[3] #=> :baz
言うまでもなく Its use is highly discouraged. ですね。irb で実行したらなんか落ちました (笑)
irb(main):001:0> class Array irb(main):002:1> alias aref_org [] irb(main):003:1> def [](x) irb(main):004:2> aref_org(x - 1) irb(main):005:2> end irb(main):006:1> end => nil irb(main):007:0> [:foo, :bar, :baz][1] SyntaxError: compile error (irb):7: syntax error, unexpected $end, expecting tSTRING_CONTENT or tSTRING_DBEG or tSTRING_DVAR or tSTRING_END from (irb):7 from :0
追記:
当然、これでは不十分です。 a[1, 2]やa[1..2]の場合に対応できていません。
http://d.hatena.ne.jp/rubikitch/20080524/1211627661
他にも配列のインデックスを扱うArray#values_atとか、Array#indexとかもありますし。
ごもっともです。本気でほしがられてるとは思いませんでした。るびきちさんに書いても釈迦に説法ですが、このくらいで許してください (笑)
class OffsetArray < Array @@o = 0 def [](*r) a, b = r return super(a - @@o, b) if r.size == 2 return super(a.begin - @@o .. a - @@o) if a.is_a?(Range) return super(a - @@o) end def []=(*r) a, b, c = r return super(a - @@o, b, c) if r.size == 3 return super(a.begin - @@o .. a - @@o, b) if a.is_a?(Range) return super(a - @@o, b) end def at(a) super(a - @@o) end def delete_at(a) super(a - @@o) end def each_index super {|a| yield(a + @@o) } end def fetch(*r, &b) r[0] -= @@o super(*r, &b) end def fill(*r, &b) r[b ? 0 : 1] -= @@o super(*r, &b) end def index(*r, &b) r = super r ? r + @@o : nil end def indexes(*r) super(*r.map {|i| i - @@o }) end alias indices indexes def insert(*r, &b) r[0] -= @@p super(*r, &b) end def rindex(*r, &b) r = super r ? r + @@o : nil end alias slice [] def slice!(*r) a, b = r return super(a - @@o, b) if r.size == 2 return super(a.begin - @@o .. a - @@o) if a.is_a?(Range) return super(a - @@o) end alias values_at indexes def self.begin @@o end def self.begin=(offset) @@o = offset end end a = OffsetArray[:foo, :bar, :baz] p a[1] #=> :bar OffsetArray.begin = 1 p a[1] #=> :foo
テストしてません。Enumerator の each_with_index はスルーで*1。あと 0 が終わりの要素でいいのかとか。