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

}.call

My first attempt was to use it like this:

# WRONG USAGE!!!!
x = ID_GENERATOR.call
puts(x) # -> SERVER0000001
y = ID_GENERATOR.call
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:

# CORRECT USAGE!!!!
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
request:

a='abc'
b=a
a='xyz'

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

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

}}.call

or

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

id.succ!.clone }}.call

hi,

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
}}.call

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

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs