Method returning a hash, is the hash in the heap?

For this program:

class Point
  def initialize(x,y)
    @x,@y = x,y
    @something = 123.456
  end

  def instance_variables_and_values
    hash = {}
    instance_variables.each {|n| hash[n] = instance_variable_get(n)}
    return hash
  end

end

p1 = Point.new(1,2)
p p1.instance_variables_and_values

p2 = Point.new(3,4)
p p1.instance_variables_and_values
p p2.instance_variables_and_values

so the hash is actually allocated in the Heap, and the local variable in
the Stack is just the "hash" reference?

So when the method returns, the "hash" variable, which is just a
reference to the hash object, is destroyed. But the hash object that is
in the Heap will stay as long as there is a reference to it (a reference
from outside)?

···

--
Posted via http://www.ruby-forum.com/.

For this program:

class Point
def initialize(x,y)
@x,@y = x,y
@something = 123.456
end

def instance_variables_and_values
hash = {}
instance_variables.each {|n| hash[n] = instance_variable_get(n)}
return hash
end

end

p1 = Point.new(1,2)
p p1.instance_variables_and_values

p2 = Point.new(3,4)
p p1.instance_variables_and_values
p p2.instance_variables_and_values

so the hash is actually allocated in the Heap, and the local variable in
the Stack is just the "hash" reference?

It is just _a_ reference - there can be multiple references to an
instance and none of them is special.

So when the method returns, the "hash" variable, which is just a
reference to the hash object, is destroyed. But the hash object that is
in the Heap will stay as long as there is a reference to it (a reference
from outside)?

Yep, basically that's it. I would pick a tad different wording but
you have grokked the essence of it.

With references we usually do not speak of "destruction" because that
is something typically done to objects. References are simply
forgotten or lost, I would say.

The lifetime of an instance is more accurately described as "from its
creation until GC decides to remove it". Of course, the earliest
point in time when GC can decide to remove it is after the last
reference to the instance has gone. (Note there is a special case
with WeakReference but I don't want to complicate things too much
initially. There are also ways to access an instance during the period
between "last ref gone" and "GC removed it" via ObjectSpace but this
is not something you should rely on.)

Kind regards

robert

···

2010/5/20 Jian Lin <blueskybreeze@gmail.com>:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Robert Klemme wrote:

The lifetime of an instance is more accurately described as "from its
creation until GC decides to remove it". Of course, the earliest
point in time when GC can decide to remove it is after the last
reference to the instance has gone. (Note there is a special case
with WeakReference but I don't want to complicate things too much
initially. There are also ways to access an instance during the period
between "last ref gone" and "GC removed it" via ObjectSpace but this
is not something you should rely on.)

yes, because previous, I was thinking that any local variables will get
erased and the stack will shrink, so in this case, the hash seems valid
and it is actually a new object creation, something that is like a
malloc()... and it resides in the heap.

for the WeakReference... the wiki explanation is "weakly reachable"... I
thought it can be garbage collected when there is not usable reference
that can reach that object... but what if it is still "reachable, but
weakly", then it can still be garbage collected? Then won't the
reference to it and its usage cause a segmentation fault or similar
error?

···

--
Posted via http://www.ruby-forum.com/\.

Robert Klemme wrote:

The lifetime of an instance is more accurately described as "from its
creation until GC decides to remove it". Of course, the earliest
point in time when GC can decide to remove it is after the last
reference to the instance has gone. (Note there is a special case
with WeakReference but I don't want to complicate things too much
initially. There are also ways to access an instance during the period
between "last ref gone" and "GC removed it" via ObjectSpace but this
is not something you should rely on.)

yes, because previous, I was thinking that any local variables will get
erased and the stack will shrink, so in this case, the hash seems valid
and it is actually a new object creation, something that is like a
malloc()... and it resides in the heap.

Exactly.

for the WeakReference... the wiki explanation is "weakly reachable"... I
thought it can be garbage collected when there is not usable reference
that can reach that object... but what if it is still "reachable, but
weakly", then it can still be garbage collected?

Yes.

Then won't the
reference to it and its usage cause a segmentation fault or similar
error?

No, you WeakRef#weakref_alive? will simply return false and
WeakRef#__getobj__ will just throw WeakRef::RefError which you will
also see for any other method.

irb(main):018:0> r.weakref_alive?
=> false
irb(main):019:0> r.to_s
WeakRef::RefError: Invalid Reference - probably recycled
        from (irb):18
        from /opt/bin/irb19:12:in `<main>'
irb(main):020:0>

The Ruby heap is not exactly the same as a heap in languages like C:
in C you directly dereference memory pointers and if there is an error
you'll get a segfault. In Ruby (as in Java as well) the runtime
system manages memory accesses and you will never see a segfault
(unless there is a bug in the runtime or in a C extension).

Kind regards

robert

···

2010/5/20 Jian Lin <blueskybreeze@gmail.com>:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/