stevenspiel
stevenspiel

Reputation: 5999

auto increment variable in Ruby

How can I auto-increment a variable so each time it is used, it is incremented by one, starting with 0?

For example:

i = i+1 || 0 

arr[i] = "foo"
arr[i] = "bar"
arr[i] = "foobar"

arr #=> ["foo","bar","foobar"]

I'm getting a NoMethodError undefined method '+' for nil:NilClass

Upvotes: 2

Views: 5917

Answers (4)

the Tin Man
the Tin Man

Reputation: 160553

This seems like what you're trying to do, but I wouldn't recommend it:

ary = []
i = -1
ary[i += 1] = 'foo'
ary[i += 1] = 'bar'
ary # => ["foo", "bar"]

Instead, do the idiomatic and expected thing and assign to an array one of these ways:

ary = ['foo', 'bar']
ary = %w[foo bar]
ary # => ["foo", "bar"]

Or, use the << operator to append on the fly, as the other answers recommend.

Upvotes: 1

David Grayson
David Grayson

Reputation: 87376

The other answers are pretty good. I would just like to add a few ways that I would implement it.

You could use a Proc:

i = -1
next_i = Proc.new { i += 1 }
next_i.call  # => 0
next_i.call  # => 1

You could use an Enumerator:

ids = Enumerator.new { |y| i = -1; loop { y << (i+=1) } }
ids.next     # => 0
ids.next     # => 1

If it makes sense in your application for the ids to come from some larger object, you could define a method in that object like this:

def next_id
  @i ||= -1
  @i += 1
end

Upvotes: 2

J&#246;rg W Mittag
J&#246;rg W Mittag

Reputation: 369420

A variable is just a name. It doesn't have behavior. If you want behavior, use a method:

def i
  @i ||= -1
  @i += 1
end

arr = []

arr[i] = 'foo'
arr[i] = 'bar'
arr[i] = 'foobar'

arr #=> ['foo', 'bar', 'foobar']

Alternatively:

_i = -1

define_method(:i) do
  _i += 1
end

arr = []

arr[i] = 'foo'
arr[i] = 'bar'
arr[i] = 'foobar'

arr #=> ['foo', 'bar', 'foobar']

But really, what you have is just a very convoluted way of saying

arr = %w[foo bar foobar]

which is much clearer.

Upvotes: 5

Chuck
Chuck

Reputation: 237010

You can't. There is no way to associate variables with behaviors — in fact, doing anything with local variables besides just reading and setting them in the obvious way is nigh impossible in standard Ruby — and integers cannot change value.

However, if you are really looking to do something like this with an arrays, you can just use the << operator to push to the end of the array:

arr = []
arr << "foo"
arr << "bar"
arr << "foobar"

arr #=> ["foo","bar","foobar"]

Upvotes: 2

Related Questions