Why do I need to clone in this case?

I have a generator, which on each invocation generates a new ID:

 ID_GENERATOR = Proc.new { id = 'SERVER0000000'; lambda { id.succ! }


My first attempt was to use it like this:

puts(x) # -> SERVER0000001
puts(y) # -> SERVER0000002

However, when I now output x again, I see that it has changed its value:

puts(x) # -> SERVER0000002

x and y share the same object. The remedy is to use it like this:

x = ID_GENERATOR.call.clone
puts(x) # -> SERVER0000001
y = ID_GENERATOR.call.clone
puts(y) # -> SERVER0000002
puts(x) # -> SERVER0000001

Now my question: Where does the “sharing” of an object occur? After all,
ID_GENERATOR.call returns a string, and strings are usually copied on


The last assignment does NOT change the value of b. Why do I get this
strange effect of object sharing with my ID_GENERATOR?

Raja gopalan wrote in post #1175194:

In your first case, it returns the same object_id, that means it
modifies the same object and returns it.

I see - the ‘succ!’ is the culprit, because it just modifies the same
object “in place”, not producing a new object id.

Hence, I have two possibilities to define my ID_GENERATOR in a better

ID_GENERATOR = Proc.new { id = 'SERVER0000000'; lambda { id=id.succ 



ID_GENERATOR = Proc.new { id = 'SERVER0000000'; lambda { 

id.succ!.clone }}.call


In your first case, it returns the same object_id, that means it
modifies the same object and returns it. To understand the second case,
you need to understand the way Ruby works when something is assigned.

For an example,
Whenever there is a new assignment happens, it creates a new object and
it assign it. For an example,

irb(main):001:0> a=‘abc’
=> “abc”
irb(main):002:0> a.object_id
=> 23636376
irb(main):003:0> b=a
=> “abc”
irb(main):004:0> b.object_id
=> 23636376
irb(main):005:0> a=‘xyc’
=> “xyc”
irb(main):006:0> b.object_id
=> 23636376
irb(main):007:0> a.object_id
=> 23685216

but In Fixnum case is different, here numbers would be acting as a name,
only when different number is being assigned object_id would get
changed, For an example,

irb(main):008:0> a=100
=> 100
irb(main):009:0> a.object_id
=> 201
irb(main):010:0> a=50+50
=> 100
irb(main):011:0> a.object_id
=> 201

oh ok, All right,

I find this one is meaningful

ID_GENERATOR = Proc.new { id = ‘SERVER0000000’; lambda { id=id.succ

Because why do you modify the same object and then clone it