0

I would like to make a function so each time it is called it return a value that is incremented by 1 starting from 1.

I guess it could be made with a global variable, but not a pretty solution.

Jasmine Lognnes
  • 6,597
  • 9
  • 38
  • 58
  • Please read "[ask]" including the linked pages, "[mcve]" and "[How much research effort is expected of Stack Overflow users?](http://meta.stackoverflow.com/questions/261592)". We'd like to see evidence of your effort. What did you try? Did you search and not find anything? Did you find stuff but it didn't help? Did you try writing code? If not, why? If so, what is the smallest code example that shows what you tried and why didn't it work? Without that it looks like you didn't try and want us to write it for you. – the Tin Man Apr 13 '17 at 23:18

2 Answers2

3

I'd probably do it this way:

class EverreadyBunnyCounter
  def initialize
    @counter = 0
  end

  def current
    @counter
  end

  def next
    @counter += 1
  end
end

foo = EverreadyBunnyCounter.new
bar = EverreadyBunnyCounter.new
foo.next # => 1
bar.next # => 1
foo.next # => 2
bar.current # => 1

The current method isn't necessary but it's sometimes convenient to be able to peek at the current value without forcing it to increment.

Alternately, this might do it:

MAX_INT = (2**(0.size * 8 -2) -1)
counter = (1..MAX_INT).to_enum # => #<Enumerator: 1..4611686018427387903:each>
foo = counter.dup
bar = counter.dup
foo.next # => 1
foo.next # => 2
bar.next # => 1
bar.next # => 2
foo.next # => 3

Defining MAX_INT this way comes from "Ruby max integer". The downside is that you'll eventually run out of values because of the range being used to create the Enumerator, where the previous version using the EverreadyBunnyCounter class will keep on going.

Changing MAX_INT to Float::INFINITY would be a way to fix that:

counter = (1..Float::INFINITY).to_enum # => #<Enumerator: 1..Infinity:each>
foo = counter.dup
bar = counter.dup
foo.next # => 1
foo.next # => 2
bar.next # => 1
bar.next # => 2
foo.next # => 3

The Enumerator documentation has more information.

Community
  • 1
  • 1
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
2

Something like this?

def incr
  @n ||= 0 
  @n += 1
end

incr
#=> 1
incr
#=> 2
spickermann
  • 100,941
  • 9
  • 101
  • 131
  • I'm coming from Python, and trying to understand a little bit about Ruby, so bear with me, but this clobbers the Object namespace, no? Might an approach with closures be a little "cleaner": [excuse what I'm sure is horribly unidiomatic code](https://repl.it/HJCe/1) – juanpa.arrivillaga Apr 13 '17 at 21:44
  • 1
    Why would it clobber the Object namespace? – the Tin Man Apr 13 '17 at 22:30