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

  • Thread starter SpringFlowers AutumnMoon
  • Start date
J

Joel VanderWerf

Austin said:
No, I don't think that's a valid comparison because a void* still
takes up space -- it's a location -- in C++. That is, I can
legitimately do:

void* a = &5;
void* b = &a;

Not quite legitimately... you didn't mean to take the address of a
literal int, did you?

Anyway, in ruby you can do:

a = [1,2,3]
b = "a"
eval b # ==> [1, 2, 3]
a = [4,5,6]
eval b # ==> [4, 5, 6]

The analogy between eval and dereferencing pointers doesn't go very far,
but this snippet does demonstrate one thing: there is some storage,
somewhere, associated with a in this context while the program is
running. Not associated with the _value_ of a (the array has its own
storage independent of a), but associated with the _variable_ itself.
Without this storage there would be no way to eval the string "a".

C/C++ doesn't have this kind of storage: there's no way to evaluate "a"
at run-time. The association between the string "a" and a certain memory
location has been compiled out, which is why the program uses the
numerical address of that location instead.

In ruby, the storage for a is in the binding for the scope of the
snippet above. You can think of the binding as something that has a
table whose entries have two fields: a variable name and a pointer to a
value (or an immediate value encoded in 4 bytes instead of a pointer).
That's a different kind of storage than heap storage, where the arrays
are. Ruby makes it harder to access the storage of a binding directly
(you have to use #eval, #binding, #local_variables), but it does take up
real space and have a location in memory.

Ruby doesn't have an operator to take the address of that location.
(Ruby doesn't have any operators for working with addresses, except for
#object_id, and this exception is just a quirk of the implementation.)
But it is a location nonetheless. You can run out of memory by
overpopulating a binding.
 
L

Lloyd Linklater

There is a lot of confusion on this one. While I know for sure that
there are low level compiled languages that will allow the pointers to
be explicitly OR implicitly called (i.e. you are not *required* to use
the dereference) I do not believe that an interpreted language would
employ specific pointers.

That having been said, what is everyone basing their positions upon? Is
this more of a debate about what things are or how to word them to
others? Where did everyone look in the docs or source code to figure
this out?
 
C

Charles Oliver Nutter

Austin said:
No, I don't think that's a valid comparison because a void* still
takes up space -- it's a location -- in C++. That is, I can
legitimately do:

void* a = &5;
void* b = &a;

It's *important* for people to understand deeply that Ruby variables
take up no space -- they're labels. If I call something a cat and you
call that same something 'Fluffy', we're still referring to the same
animal, but neither of our names for that animal can easily be
referred to by another name.

Ruby variables are "wafer-thin". They're, as I said, just sticky notes
that can be moved around at will. It's the *objects* that take up the
space.

Ruby variables take up just as much space, they just do it in the call
stack rather than on the heap. They don't move around, you can't define
new ones in a given scope after it's been parsed and activated (except
for a few oddities in eval), and they have specific locations in memory
for the duration of a given activation. Each variable name represents a
slot in the local scope of the method activation. Some slots are named,
some aren't; flip-flops, for example, get anonymous slots.

Ruby variables hold the value of an object reference. If you re-assign
them, you are setting them to a different object reference. If you
retrieve them, you're getting an object reference which you can then
pass by value or use to invoke methods.

- Charlie
 
C

Charles Oliver Nutter

SpringFlowers said:
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?

Ruby variables hold the value of an object reference. Reassigning the
variable set it to a different object reference. Retrieving the value
gives you an object reference you can then pass by value to another
method or use to invoke methods on the object.

Pointers are lower-level. You can't do pointer math with Ruby variables,
and you can never retrieve the memory address of an object, so thinking
of Ruby variables as pointers is misleading.

- Charlie
 
A

Austin Ziegler

Ruby variables take up just as much space, they just do it in the call
stack rather than on the heap.

That's an implementer's view. When I program with Ruby, I don't think of
a variable taking up space. In purely Ruby terms, a variable isn't an
object that I can manipulate. In C++ terms, I can manipulate a variable
because it's a concrete item.
Ruby variables hold the value of an object reference. If you re-assign
them, you are setting them to a different object reference. If you
retrieve them, you're getting an object reference which you can then
pass by value or use to invoke methods.

Conceptually, they're better seen as labels or sticky notes. Maybe not
for the implementers, but definitely at the normal programmer's level.
Thinking about them more than that is just asking for madness because
you can't interact with them at any other level than that.

-austin
 
G

Gary Wright

Conceptually, they're better seen as labels or sticky notes. Maybe not
for the implementers, but definitely at the normal programmer's level.
Thinking about them more than that is just asking for madness because
you can't interact with them at any other level than that.

I can see the value of the sticky note analogy but I think it
obscures the idea of scopes. It puts the variable name in close
proximity to the referred object and not the referring scope.

Think about instance variables, for example. You can have two
objects each with an instance variable that has a reference to
a common third object:

class Foo
attr_accessor :eek:ther
end

alpha = Foo.new
beta = Foo.new

gamma = Object.new

alpha.other = gamma
beta.other = gamma

Does it make sense to think of gamma as having two sticky notes
with '@other' written on them? Not to me at least.

The problem with the sticky note analogy, for me, is that it implies
that the object has access to the sticky notes--that the object
can 'see' what variables are referring to itself. The notes seem
to be 'stuck' to the wrong thing in my mind. They should be more
like a piece of paper with a name and a phone number written on it.
The name is the variable and the phone number is the reference for
the other person (object). The phone system is an opaque system
that provides a way for us to contact another person and
communicate with them (send a message to another object) without
us having to know where that person is physically located.

Gary Wright
 
7

7stud --

Austin said:
That's an implementer's view. When I program with Ruby, I don't think of
a variable taking up space. In purely Ruby terms, a variable isn't an
object that I can manipulate. In C++ terms, I can manipulate a variable
because it's a concrete item.


Conceptually, they're better seen as labels or sticky notes. Maybe not
for the implementers, but definitely at the normal programmer's level.
Thinking about them more than that is just asking for madness because
you can't interact with them at any other level than that.

Your original post was ridiculous and now you've been called out. Take
your medicine with some semblance of grace. Back pedaling as fast as
you can stirs up a cloud of dust, but we still know its you in there.
 
S

SpringFlowers AutumnMoon

Charles said:
Ruby variables hold the value of an object reference. If you re-assign
them, you are setting them to a different object reference. If you
retrieve them, you're getting an object reference which you can then
pass by value or use to invoke methods.

yes, that's what i mean by thinking of a reference to an object as a
pointer. let's say if we implement Ruby, can't we actually set it as a
pointer to the Dog object, and then whenever we use d.bark(), it will go
to where it points to and start looking for a table of method names.
and if not found, go to the parents, again using a pointer to the parent
class. i won't increment the pointer or do pointer arithmetic, and i
won't care what the pointer's value is (the address) and won't tell the
programmer, but underneath, it is still a pointer.

so

d = Dog.new("lulu") # d points to some new memory chunk
b = d # b points to the same place
d = Dog.new("woofy") # d now points to a new memory chunk
# and b points to the old chunk
 
A

Austin Ziegler

I can see the value of the sticky note analogy but I think it
obscures the idea of scopes. It puts the variable name in close
proximity to the referred object and not the referring scope.

It's an analogy. Nothing more, nothing less. There are ALWAYS limits
to analogies. The limit to the sticky note analogy is that scopes are
obscured. I don't have a problem with that, because that's not the
nature of the confusion that was being exhibited. With some
mind-bending, scopes could be dealt with in the analogy (when you
enter a new scope, you put a piece of wrapping paper over the object
and you can name things...).
The problem with the sticky note analogy, for me, is that it implies
that the object has access to the sticky notes--that the object
can 'see' what variables are referring to itself.

That's not at all implied by what I said. If I were to attach a sticky
note to the middle of your back, you wouldn't have access to it. ;)

But even if we change it to your "note with name and phone number"
concept, the important piece here is that the variable is a note, not
a container. Again, this doesn't apply to actual implementation
details, but when I'm programming in Ruby, I simply don't think about
the space a variable consumes.

-austin
 
A

Austin Ziegler

Your original post was ridiculous and now you've been called out. Take
your medicine with some semblance of grace. Back pedaling as fast as
you can stirs up a cloud of dust, but we still know its you in there.

Are you always this unpleasant, boorish, and rude?

Tell me: do you really care that a Ruby variable takes up space? You,
as a programmer, shouldn't. Can you do a damned thing about it? Nope.
In the end, it doesn't matter. Charles is *technically* correct from
the implementer's perspective. Gary Wright has provided the only valid
complaint, that I ignore scope. Well, yes, I did. On purpose. I
considered how to address it and decided it was better to ignore it
for the concept.

From a Ruby programmer's perspective, it is important to understand
that a variable is a label -- a name -- for an object, and that the
name is transferable and is always transferred on assignment (of which
a special form is argument setting in method passing). It has as much
permanence as a hastily scribbled note about an object that you're
dealing with.

Anyone telling you anything else is either (a) an implementer who has
to care about the inner details or (b) confused. (BTW, understanding
variables this way also helps demystify Symbols immensely, and there's
a lot of confusion about Symbols because people want to think that
they're some magic juju.)

-austin
 
S

Simon Krahnke

* SpringFlowers AutumnMoon (2007-09-29) said:
when we say

a = Dog.new("lulu")

Now a is not really a pointer,

»a« is a variable. A variable is never a pointer.

A variable is always a name for something in some scope.

In C and C++ a variable is a name for a location in memory. Variables
have a type that tells the C Compiler what to do when the variable is
used. [1]

In Ruby a variable is a name for an object. You can call this a
reference but just as well stick to »variable«.

When a variable name is used as an expression, the expression's value is
the object the variable is a name for.
When we use a.color, it is like a reference in C++ implicitly
dereference it and use its attributes.

Ruby is not an alternate syntax for C++.

mfg, simon .... l

[1] I am a human. I don't quite know what a C++ reference is.
 
C

Charles Oliver Nutter

SpringFlowers said:
yes, that's what i mean by thinking of a reference to an object as a
pointer. let's say if we implement Ruby, can't we actually set it as a
pointer to the Dog object, and then whenever we use d.bark(), it will go
to where it points to and start looking for a table of method names.
and if not found, go to the parents, again using a pointer to the parent
class. i won't increment the pointer or do pointer arithmetic, and i
won't care what the pointer's value is (the address) and won't tell the
programmer, but underneath, it is still a pointer.

I think the named slots holding object references analogy is probably as
accurate as you can get without getting into implementation specifics.
For example, in Ruby, the named slots *arg* pointers to objects (except
in a few cases like Fixnums). In JRuby, they're just Java references,
again passed-by-value object references. But named slots will apply
fairly well across all implementations.

- Charlie
 
C

Charles Oliver Nutter

Austin said:
Didn't I just say that they aren't the same?


But that's exactly the *WRONG* way to look at it. In Pascal, Java,
C/C++, and possibly PHP5 (again, I don't know Python's semantics), a
variable takes up space.

In Ruby, a variable doesn't contain anything. It doesn't contain an
address, it doesn't contain an object, it doesn't contain anything. It's
a label, a name, a sticky note attached to the object.

In exactly the same way as Java variables don't take up space...except
that they do. The same logic applies in both cases, and the analogy
breaks down in the same way.

A Java local variable does not take up space any differently than a Ruby
local variable takes space; it's a slot in a stack frame. I'll stick by
named slots being the most straightforward way to refer to Ruby (or
Java) local variables.

- Charlie
 
D

David A. Black

Hi --

There is a lot of confusion on this one. While I know for sure that
there are low level compiled languages that will allow the pointers to
be explicitly OR implicitly called (i.e. you are not *required* to use
the dereference) I do not believe that an interpreted language would
employ specific pointers.

That having been said, what is everyone basing their positions upon? Is
this more of a debate about what things are or how to word them to
others? Where did everyone look in the docs or source code to figure
this out?

I'm just following what I've always understood, from discussions with
Matz, the Pickaxe, etc., to be the standard terminology. From the
first edition of the Pickaxe:

"Ruby variables and constants hold references to objects. Variables
themselves do not have an intrinsic type. Instead, the type of a
variable is defined solely by the messages to which the object
referenced by the variable responds."

The explanation goes into more depth but that's the basics. I've never
felt the need or desire to reconcile this with C++ or anything else.
It's always seemed straightforward to me.


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

Rick DeNatale

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

And moving a sticky note to another object leaves any other sticky
notes where they are.
A Ruby variable is nothing like a C++ variable. Never has been, never
will be.

Excellent exposition!
(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.)

There's nothing special in this regard about immediate objects like 0,
99, nil, true... either. You can stick as many post-it notes on these
as you want, even though there's only one of each.

The technical name for what these post-it notes 'hold' is an object
reference. It's an opaque value which the implementation can use to
'finger' a particular object. This shouldn't be confused with the
object id which you might think of as a unique serial number magically
stamped onto each object.

And as I pointed out on another thread today, if you think of the
parameter passing mechanism as neither call by value, or call by
reference, but as call by object reference it might clarify things.
[*] 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.

At some early OOPSLA (late 1980s/early 1990s) Apple was showing off
their new C++ compiler for the Macintosh Programmers Workshop.

Stroustrup was strolling through the exhibits and wandered into the
Apple booth. One of the Apple guys grabbed him and proudly showed him
that Apple now had a C+ compiler.

Bjarne stood at the computer and typed in a little "Hello world" C++ program.

After about 3 or four tries HE finally got all of the syntax errors
out of his trial program, and this wasn't due to bugs in Apple's
compiler.
 
R

Robert Dober

Stroustrup was strolling through the exhibits and wandered into the
Apple booth. One of the Apple guys grabbed him and proudly showed him
that Apple now had a C+ compiler.

Bjarne stood at the computer and typed in a little "Hello world" C++ prog= ram.

After about 3 or four tries HE finally got all of the syntax errors
out of his trial program, and this wasn't due to bugs in Apple's
compiler.
But these things happen sometimes, was there not a famous guy in the
Perl community - called Leo T=F6tsch IIRC - who wrote tons of patches
for the perl interpreter hardly knowing Perl?

BTW, Matz could you please post a correct Hello World program in Ruby,
you do not have to get it right the first time, second time still
beats Bjarne ;).

Robert


--=20
what do I think about Ruby?
http://ruby-smalltalk.blogspot.com/
 
G

Guest

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/Refere...)http://en.wikipedia.org/wiki/Reference_(C++)

)

Yes! You're right.
It's really not "reference" or "value" or "pointer" in c++ sense.

Some body calls it "reference to object" or something else.
Anyway, if you want to use conceptions in c++ sense to describe it.
It works like (i said somewhere before)....
when it's used as a left value, it works like a pointer, which means
the variable doesn't have the object. it only points to the object.
when it's used as a right value, it dereference automatically.
 

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,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top