a = Dog.new # a is not a pointer and not a reference?

  • Thread starter SpringFlowers AutumnMoon
  • Start date
S

SpringFlowers AutumnMoon

when we say

a = Dog.new("lulu")

Now a is not really a pointer, because we don't need to dereference it
to use it, like

(*a).color = "red"
a->color = "red"

When we use a.color, it is like a reference in C++ implicitly
dereference it and use its attributes.

But then a is not really a reference (like C++), because we can say

a = nil or a = Dog.new("woofy")

and now a points to some where else. With reference, once a reference
is set, it cannot point to some where else (in C++).

So it is kind of a mixture of pointer and reference?

Or, we can think of it as a pointer, and then think of "." as the "->"
in C++.

In that case, we can say that a is a pointer and not a reference.

And it seems the same way in Java, Python, and PHP5.

(Pointers and References discussed in

http://en.wikipedia.org/wiki/Reference_(computer_science)
http://en.wikipedia.org/wiki/Reference_(C++)

)
 
M

Morton Goldberg

when we say

a = Dog.new("lulu")

Now a is not really a pointer, because we don't need to dereference it
to use it, like

(*a).color = "red"
a->color = "red"

When we use a.color, it is like a reference in C++ implicitly
dereference it and use its attributes.

But then a is not really a reference (like C++), because we can say

a = nil or a = Dog.new("woofy")

and now a points to some where else. With reference, once a reference
is set, it cannot point to some where else (in C++).

So it is kind of a mixture of pointer and reference?

Or, we can think of it as a pointer, and then think of "." as the "->"
in C++.

In that case, we can say that a is a pointer and not a reference.

And it seems the same way in Java, Python, and PHP5.

I think it best to think of a Ruby variable as holding a reference to
an object. Ruby's reference semantics are different from C++'s, but
IMO more mainstream. C++'s reference semantics are peculiar, to say
the least, and perhaps even unique [*]. Ruby's variable semantics are
simple and clean when compared to C++, so I recommend forgetting
about making such comparisons.

Regards, Morton

[*] Betrand Meyer of Eiffel fame has often made fun of C++'s
reference semantics. He has claimed they are beyond the understanding
of mere mortals. He is joking, of course.
 
7

7stud --

SpringFlowers said:
With reference, once a reference
is set, it cannot point to some where else (in C++).

Sort of sounds like a constant pointer, doesn't it?
 
D

David A. Black

Hi --

when we say

a = Dog.new("lulu")

Now a is not really a pointer, because we don't need to dereference it
to use it, like

(*a).color = "red"
a->color = "red"

When we use a.color, it is like a reference in C++ implicitly
dereference it and use its attributes.

But then a is not really a reference (like C++), because we can say

a = nil or a = Dog.new("woofy")

and now a points to some where else. With reference, once a reference
is set, it cannot point to some where else (in C++).

So it is kind of a mixture of pointer and reference?

It's a reference; at least, that's the term I've always heard Matz and
others use, never 'pointer'. When you do this:

d = Dog.new("lulu")

you have assigned a reference to the dog object to the variable d. As
you mention, you don't have to dereference it; you can send messages
to an object reference, and they'll go to the object:

d.bark # sending message 'bark' to the Dog object

When you then do this:

d = nil

you're starting again, re-using 'd' as an identifier. There's
absolutely no connection to the previous use of 'd'.
Or, we can think of it as a pointer, and then think of "." as the "->"
in C++.

I would try to think entirely in Ruby. It never quite works to
transliterate one language's semantics into another's.

The '.' means: send the following message to the object on the dot's
left, where the object can be a literal, a variable, or a method call:

a = "abc"
a.upcase
"abc".upcase
def d
Dog.new("lulu")
end
d.bark
In that case, we can say that a is a pointer and not a reference.

I wouldn't say it's a pointer. "Reference" is the universal term, as
far as I've heard.

One thing to keep in mind about objects and references in Ruby is that
every reference to an object is exactly one step away from the object,
and there are no references to references. So you never get into
pointer arithmetic and chaining.


David

--
Upcoming training from Ruby Power and Light, LLC:
* Intro to Ruby on Rails, Edison, NJ, October 23-26
* Advancing with Rails, Edison, NJ, November 6-9
Both taught by David A. Black.
See http://www.rubypal.com for more info!
 
S

SpringFlowers AutumnMoon

Morton said:
On Sep 29, 2007, at 1:16 PM, SpringFlowers AutumnMoon wrote:

I think it best to think of a Ruby variable as holding a reference to
an object. Ruby's reference semantics are different from C++'s, but
IMO more mainstream. C++'s reference semantics are peculiar, to say
the least, and perhaps even unique [*]. Ruby's variable semantics are
simple and clean when compared to C++, so I recommend forgetting
about making such comparisons.

hm... so you mean best to think of a Ruby variable as holding a pointer
to an object? I hope either

1) we use the word "reference" to mean a pointer
2) or, we just use the word pointer instead,

that's because "reference" seems to mean something different in both
C++, PHP, and in the general computer science area.
 
7

7stud --

David said:
I wouldn't say it's a pointer. "Reference" is the universal term, as
far as I've heard.

What language is ruby written in? (Not jRuby or IronRuby.)
 
G

Gary Wright

Morton said:
On Sep 29, 2007, at 1:16 PM, SpringFlowers AutumnMoon wrote:

I think it best to think of a Ruby variable as holding a reference to
an object. Ruby's reference semantics are different from C++'s, but
IMO more mainstream. C++'s reference semantics are peculiar, to say
the least, and perhaps even unique [*]. Ruby's variable semantics are
simple and clean when compared to C++, so I recommend forgetting
about making such comparisons.

hm... so you mean best to think of a Ruby variable as holding a
pointer
to an object? I hope either

1) we use the word "reference" to mean a pointer
2) or, we just use the word pointer instead,

I think that 'pointer', for most programmers, means an explicit memory
address. Ruby references should not be understood as explicit memory
addresses but instead as opaque values that are processed by the
underlying Ruby implementation as necessary to locate or 'reference'
the associated object.

At the level of a Ruby programmer I think it is best to discard the
idea of 'pointer' entirely and think entirely about references to
objects. At the level of a Ruby language implementor it becomes
necessary at some point to discuss how a Ruby reference can be
converted to a pointer to a chunk of memory, but that is an
implementation
detail that shouldn't concern a Ruby application programmer.

Gary Wright
 
J

John Joyce

Morton said:
On Sep 29, 2007, at 1:16 PM, SpringFlowers AutumnMoon wrote:

I think it best to think of a Ruby variable as holding a
reference to
an object. Ruby's reference semantics are different from C++'s, but
IMO more mainstream. C++'s reference semantics are peculiar, to say
the least, and perhaps even unique [*]. Ruby's variable semantics
are
simple and clean when compared to C++, so I recommend forgetting
about making such comparisons.

hm... so you mean best to think of a Ruby variable as holding a
pointer
to an object? I hope either

1) we use the word "reference" to mean a pointer
2) or, we just use the word pointer instead,

I think that 'pointer', for most programmers, means an explicit memory
address. Ruby references should not be understood as explicit memory
addresses but instead as opaque values that are processed by the
underlying Ruby implementation as necessary to locate or 'reference'
the associated object.

At the level of a Ruby programmer I think it is best to discard the
idea of 'pointer' entirely and think entirely about references to
objects. At the level of a Ruby language implementor it becomes
necessary at some point to discuss how a Ruby reference can be
converted to a pointer to a chunk of memory, but that is an
implementation
detail that shouldn't concern a Ruby application programmer.

Gary Wright
Yep.
You're not guaranteed (AFAIK) any direct memory access in Ruby, nor
should you be concerned about it. It is Ruby. The goal is to allow
you to focus on programming and making things happen. If you want
access and control at a lower level, you'll need to use a language
like C or C++ or perhaps Objective-C (don't know if Obj-C 2.0, coming
in a month or so, will allow such low level access)
In Ruby just think about identifiers as references to objects. The
only case that requires a little time to get a hang of is Ruby's
Symbol class. They could be described as constant references (for the
life of the program) and should be used carefully like globals. You
don't want too many of them, but with any modern system you should
have reasonable amount of headroom, unless you're dealing with a huge
data set.
With Ruby, like SmallTalk, you're pretty much always dealing with
objects and nothing much lower-level like pointers or primitive types.
 
J

Julian Tarkhanov

In that case, we can say that a is a pointer and not a reference.

This has been discussed at greatest length imaginable. Personally I
use the somwehat unacademic
"a direct reference to an object in the heap" for variables in Ruby.
Whereby the reference is just that -
a handle, not a value in itself (some address of something or other).
The only moment when it is handy to knowis when doing assignment.

boo = Dog.new # this makes a new Dog in the heap and saves it's
"handle" in boo
boo = nil # this wil NOT replace the new Dog in the heap with a nil,
but will link boo to the single instance of NilClass - the dog will
stay in the heap and will eventually
# be GCed

From there comes the Object#replace method.

For the rest you can more-less safely assume that everything happens
by reference.
 
A

Austin Ziegler

On Sep 29, 2007, at 1:16 PM, SpringFlowers AutumnMoon wrote:

Please forget anything and everything you ever learned about pointers
and references with respect to Ruby. It simply doesn't apply. This is a
good thing.

No, it isn't a pointer. Period. I'm going to introduce a new concept to
you in a moment.

No, that's not true. You can, with some difficulty, rereference.

No, you can't.

No, you can't.

I can't speak toward Python, but Java and PHP treat variables
differently than Ruby.

A variable in Ruby isn't like Java, PHP, C++, C, or even Pascal.
I think it best to think of a Ruby variable as holding a reference to
an object. Ruby's reference semantics are different from C++'s, but
IMO more mainstream. C++'s reference semantics are peculiar, to say
the least, and perhaps even unique [*]. Ruby's variable semantics are
simple and clean when compared to C++, so I recommend forgetting
about making such comparisons.

No, it's best to forget the concept of a Ruby variable as a shoebox. It
doesn't *hold* anything.

In C/C++, a variable is a shoebox. This shoebox has a physical location
and dimension (the address in memory). One shoebox can hold the location
of another shoebox. That's a pointer or a reference (under the covers,
they are the same in C++).

A variable in Ruby is a sticky note (like a Post-It). You can put that
sticky note on an object, or you can put multiple sticky notes on an
object. But if you move the sticky note, you're changing the object to
which it references. Since they're labels, the sticky notes don't
contain anything -- they just name the object that they're attached to.
Since they don't contain anything, no other sticky note can point to
another sticky note.

A Ruby variable is nothing like a C++ variable. Never has been, never
will be.

(Don't think that Symbols are special, either. They're not. Ruby just
keeps a list of all sticky notes that were ever created so you can,
within a certain scope and context, see if the objects you want know
anything about those particular sticky notes. It's sort-of a master
index, that way. But it's not magic. It's how you use them that's
magic.)
[*] Betrand Meyer of Eiffel fame has often made fun of C++'s reference
semantics. He has claimed they are beyond the understanding of mere
mortals. He is joking, of course.

No, he's not. Bjarne is clearly not a mere mortal. Or from the upper
planes.

-austin
 
A

Austin Ziegler

From there comes the Object#replace method.

There is no Object#replace method. String, Array, and Hash each have
#replace methods, but Object does not.

-austin
 
J

Joel VanderWerf

Austin Ziegler wrote:
...
No, it's best to forget the concept of a Ruby variable as a shoebox. It
doesn't *hold* anything.

In C/C++, a variable is a shoebox. This shoebox has a physical location
and dimension (the address in memory). One shoebox can hold the location
of another shoebox. That's a pointer or a reference (under the covers,
they are the same in C++).

A variable in Ruby is a sticky note (like a Post-It). You can put that
sticky note on an object, or you can put multiple sticky notes on an
object. But if you move the sticky note, you're changing the object to
which it references. Since they're labels, the sticky notes don't
contain anything -- they just name the object that they're attached to.
Since they don't contain anything, no other sticky note can point to
another sticky note.

A Ruby variable is nothing like a C++ variable. Never has been, never
will be.

It's not so mysterious. If you're coming from C/C++, you may find it
helpful to think of a ruby variable as a C void* variable. Assigning
between variables in ruby is just like C assignment between two void* vars.

In many cases, the void* points to a struct with the data of the object,
including some flags, a pointer to the class of the object, a pointer to
the table of instance variables, and so on. Assignment copies the void*
pointer (4 bytes), not the struct (20+ bytes).

In a few cases, the void* isn't really a pointer, but an immediate
value: a fixnum, boolean, or symbol. In those cases, though, you can
just as well think of it as a pointer to a unique instance of the number
42, or whatever. At least, that's a useful fiction when you're writing
ruby code, but not when you're writing an extension in C.

If you're not coming from C/C++, the following metaphor (maybe a
variation on the sticky metaphor, but I like it better) may help:

On a piece of paper, draw a vertical line. On the left of the line,
write down some variable names:

x
y
z

On the right of the line, write down some values:

1
7.2
false
"hello, world"
[ [1, 0], [0, 1] ]

Now, draw some arrows from left to right, connecting names with values.
Make sure that each name has only one arrow coming out of it. (Those
arrows are together called a binding.) The things on the right have a
physical location in memory. The things on the left do too, but in a
more subtle way.

What the assignment "y = x" means is: look at the value that the arrow
from x leads to, then erase the arrow that starts from y (if any), and
draw a new arrow from y to the same value that's connected to x. You
should now have one arrow from x and one arrow from y, both leading to
the same value on the right.

If you keep this diagram in mind, you'll understand why the following
happens in ruby:

x = [2,3]
y = x
x[1] = 4
p y[1] # ==> 4

and you'll also understand why

x = 0
x++

can't make any sense.

This arrow diagram isn't the whole picture of course: eval breaks down
the wall between variable name and value, and there are different
bindings in different scopes. But there's nothing fundamentally wrong
with this picture.
 
M

Morton Goldberg

On 9/29/07, Morton Goldberg <[email protected]> wrote:

A variable in Ruby isn't like Java, PHP, C++, C, or even Pascal.
I think it best to think of a Ruby variable as holding a reference to
an object. Ruby's reference semantics are different from C++'s, but
IMO more mainstream. C++'s reference semantics are peculiar, to say
the least, and perhaps even unique [*]. Ruby's variable semantics are
simple and clean when compared to C++, so I recommend forgetting
about making such comparisons.

My use of "holding" may be unfortunate. I only meant it conceptually.
I was trying to make things simple for the OP.
No, it's best to forget the concept of a Ruby variable as a
shoebox. It
doesn't *hold* anything.

In C/C++, a variable is a shoebox. This shoebox has a physical
location
and dimension (the address in memory). One shoebox can hold the
location
of another shoebox. That's a pointer or a reference (under the covers,
they are the same in C++).

A variable in Ruby is a sticky note (like a Post-It). You can put that
sticky note on an object, or you can put multiple sticky notes on an
object. But if you move the sticky note, you're changing the object to
which it references. Since they're labels, the sticky notes don't
contain anything -- they just name the object that they're attached
to.
Since they don't contain anything, no other sticky note can point to
another sticky note.

By "sticky notes" you seem to be talking about bindings, like a Lisp
variable makes. That is how I think of Ruby variables, myself, but I
didn't think bringing bindings up would help the OP. I didn't think
of the analogy with sticky notes. I like that -- I'll have to
remember it.
A Ruby variable is nothing like a C++ variable. Never has been, never
will be.

We are in complete agreement. That was the point I trying to make.
Did I phrase it so obscurely that you took me to be saying the opposite?
[*] Betrand Meyer of Eiffel fame has often made fun of C++'s
reference
semantics. He has claimed they are beyond the understanding of mere
mortals. He is joking, of course.

That should be Bertrand not Betrand. Pardon my typo.
No, he's not. Bjarne is clearly not a mere mortal. Or from the
upper planes.

Are you implying Bjarne Stroustrup is some kind of demon? He always
struck me as a very nice person.

Regards, Morton
 
D

David A. Black

Hi --

What language is ruby written in? (Not jRuby or IronRuby.)

C. It sounds like you're asking the question rhetorically, though. I'm
not sure what you mean.


David

--
Upcoming training from Ruby Power and Light, LLC:
* Intro to Ruby on Rails, Edison, NJ, October 23-26
* Advancing with Rails, Edison, NJ, November 6-9
Both taught by David A. Black.
See http://www.rubypal.com for more info!
 
J

Julian Tarkhanov

There is no Object#replace method. String, Array, and Hash each have
#replace methods, but Object does not.

Sure. Mistake on my part. But the semantics of something#replace are
different than an assignment to a variable, that's what I meant.
 
S

SpringFlowers AutumnMoon

Austin said:
A variable in Ruby isn't like Java, PHP, C++, C, or even Pascal.

Doesn't a Ruby variable behave the same way in Java, PHP5, C++, and
Python?

As long as I view Ruby as a pointer to an object, everything clicks.

Except until it is the C++ int &i = a or PHP's int $a =& $b
then things start to get weird.. they call it reference...

and it behaves like this:

<?php

class Dog {
var $name;

function Dog($i) {
$this->name = "I'm $i!\n";
}
}

$a = new Dog("lulu"); # a is a reference to "lulu" object
$c = $a; # c is a reference to "lulu" object
$b = &$a; # b is a reference to reference ?
$b = new Dog("woofy");

echo "This is PHP ", phpversion(), "\n\n";

print_r($a);
print_r($b);
print_r($c);

?>

C:\rails\depot>php assign2.php
This is PHP 5.2.4

Dog Object
(
[name] => I'm woofy!

)
Dog Object
(
[name] => I'm woofy!

)
Dog Object
(
[name] => I'm lulu!

)

First of all, we don't have things like $b =& $a in Ruby, right? So in
Ruby, we are very simple and clear.

Second, the PHP code above, $b is a reference (to reference), you see
when you change $b, you are changing the thing it is referring to. In
this case, changing where $a is referring to. There is no way you just
ask $b to refer some where else unless you use the unset() function.

Maybe in Ruby, a = Dog.new("lulu") we call a as a reference... then we
can't really let "a" reference another object like using a =
Dog.new("woofy"). However, if you don't say a is a reference, but a
"contains" a reference, then it might be possible... then you can let a
contain a different reference.

I think in Ruby, if we say "a" is a pointer, i can understand that. if
we say "a" is a reference, then i can't understand it, as a reference in
the computer science field is that you can't change where it points to
or refers to. you always have to change the object where it refers to.
but if you say "a" contains a reference... then i think that's fine,
because "a" can contain a reference but it can contain another
reference, and it is pointing else where.

somehow, i think calling int &i = a in C++ or $a =& $b in PHP as
reference is somewhat confusing, as people tend to think reference
meaning a pointer beforehand. If we call int& i = a in C++ and $a =& $b
just alias, then things are more clear. Put it this way, if those
things are called alias, then will we say in Ruby, a = Dog.new("lulu")
as an "alias" to the object lulu? or will we call a "a reference" to
the object lulu.
 
S

SpringFlowers AutumnMoon

SpringFlowers said:
$a = new Dog("lulu"); # a is a reference to "lulu" object
$c = $a; # c is a reference to "lulu" object
$b = &$a; # b is a reference to reference ?
$b = new Dog("woofy");


actually, i think it would be better to name them differently:

$a = new Dog("lulu"); # a is a reference to "lulu" object
$c = $a; # c is a reference to "lulu" object
$b = &$a; # b is an alias to reference ?
$b = new Dog("woofy");

or

$a = new Dog("lulu"); # a is a pointer to "lulu" object
$c = $a; # c is a pointer to "lulu" object
$b = &$a; # b is a reference to pointer ?
$b = new Dog("woofy");

as they are different things. before, i tend to think of alias as just
a pointer, but people in C++ and Java told me i can't, because pointer
can point any where, but an alias cannot. we cannot change where an
alias points to, and if we change anything, it will always be changing
the thing where it points to.

Come to think about it, a pointer is very clear cut... an alias is very
clear cut. but when it is "reference", then you have to think whether
it is the pointer behavior or the alias behavior.
 
M

Morton Goldberg

Come to think about it, a pointer is very clear cut... an alias is
very
clear cut. but when it is "reference", then you have to think whether
it is the pointer behavior or the alias behavior.

No, you do not. Ruby has it own semantics, which do not correspond
with the semantics of C or C++. Trying to impose the semantics of
other languages onto Ruby isn't going to work. It's best to drop such
baggage and start fresh.

Try this. Without going into implementation details, of which I am
ignorant, a Ruby variable establishes an association between an
identifier and an object [*]. The association is specific to a
particular lexical scope and to a particular execution extent.
Therefore the same identifier can be associated (refer to) different
objects in different scopes and different objects at different points
of the execution. Such an association should perhaps more strictly be
called a binding rather than a reference, but 'reference' is often
used in informal discourse.

This the way I think of it. It's an old Lisp programmer's point of
view, but I think it's a reasonably good model for Ruby. It has
worked well for me -- kept me out of trouble. And if I'm guilty of
wrongly imposing Lisp semantics on Ruby, I'm sure I'll be corrected :)

Regards, Morton

[*] Yes, I know this is not the whole story. I'm trying to keep
things simple.
 
S

SpringFlowers AutumnMoon

Morton said:
No, you do not. Ruby has it own semantics, which do not correspond
with the semantics of C or C++. Trying to impose the semantics of
other languages onto Ruby isn't going to work. It's best to drop such
baggage and start fresh.

hm,... but is there a problem to think of reference in Ruby as a
"pointer"? will that cause any trouble? I only see that a.value is
not the same as C and C++ would use a->value, but in Ruby we use the "."
to replace the "->" and that's it. Will there be further trouble or
discrepancy to think of Ruby reference as a pointer?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top