a different type of reference (shocked)

  • Thread starter SpringFlowers AutumnMoon
  • Start date
S

SpringFlowers AutumnMoon

Before, when I say Ruby's reference to an object

a = Car.new
b = a

i was saying a is a reference to a Car object. and b is now the same
reference to that object.

I mean it the very traditional pointer way:

int a = 10;
int *ip, *jp;
ip = &a;
jp = ip;

Now I didn't know that, as someone told me, that there is another type
of reference in C++, Java, and PHP:


i = 10
j =& i
j = 20
// and now both i and j are 20 (!!! shocked)
// is it to think of j as jpp? a pointer to pointer to int,
// and j = 20 involves implicit deferencing? **jpp = 20
// or if it is an object, *jp = &obj ?


so I think when people talk about assignment in Python, Java, and Ruby,

a = b

is the first type of "Pointer reference"

and the second type is a "Alias reference"

Isn't that the case? Is the above true so far?

In the PHP docs, it seems they intermix the two, and talk about PHP4's
=& the same way as PHP5's $obj1 = $obj2... and that was somewhat
imprecise. In Ruby, we only have the "pointer reference" and that's it.
No need to worry about "alias" here and there.

(and in Ruby, we call a method by "pass by value, the value being the
reference (pointer) to an object). and when the method returns
something, it returns a value, which is the reference to an object.) It
is very consistent all the way. In Ruby, we don't have the "alias
reference", right?
 
P

Phlip

SpringFlowers said:
(and in Ruby, we call a method by "pass by value, the value being the
reference (pointer) to an object). and when the method returns
something, it returns a value, which is the reference to an object.) It
is very consistent all the way. In Ruby, we don't have the "alias
reference", right?

In Ruby, types that can (generally) fit into 32 bits are "immediate
types". These Fixnums and Floats are pass-by-value. All other types -
from String up - are pass by reference:

def foist(q)
q.replace('yo')
end
q = 'otherwise'
foist(q)
assert_equal 'yo', q

Nothing to be shocked about, because you should not scribble on your
input arguments anyway. If you need some other value inside a method,
it should get its own variable with a distinct name.
 
P

Phrogz

In Ruby, types that can (generally) fit into 32 bits are "immediate
types". These Fixnums and Floats are pass-by-value. All other types -
from String up - are pass by reference:

But I don't think this should make any bit of difference to anyone.
Pass-by-value of an 'immediate' object is (nearly) indistinguishable
for pass-by-reference of an immutable object. The only consistent
difference that I can think of is that two literals of the same value
happen to have the same object_id. (And as has been pointed out
recently, there are very few good reasons why you should care about
object_id other than possibly debugging.)
 
7

7stud --

SpringFlowers said:
Before, when I say Ruby's reference to an object

a = Car.new
b = a

i was saying a is a reference to a Car object. and b is now the same
reference to that object.

I mean it the very traditional pointer way:

int a = 10;
int *ip, *jp;
ip = &a;
jp = ip;

Now I didn't know that, as someone told me, that there is another type
of reference in C++, Java, and PHP:


i = 10
j =& i
j = 20
// and now both i and j are 20 (!!! shocked)

Not so shocking.

int x = 10;
int* p1 = &x;
int* p2 = p1;
*p2 = 5;

cout<<*p1<<" "<<*p2<<endl; //5 5

A C++ reference, which is a different type than a pointer in C++, is
actually implemented as a pointer behind the scenes. However, C++
references allow you to use a different syntax that doesn't require
dereferencing:

int x = 10;
int& r = x; //r becomes a pointer to the same address as x
r = 5;

cout<<x<<" "<<r<<endl; //5 5

In C++, references are sometimes called 'aliases'. But ruby also has
aliases:

x = "hello"
y = x

y[0] = "H"
puts x, y //Hello Hello

In ruby, x and y are aliases for the same object, i.e. both names refer
to the same object, i.e. the object has two different names. The
difference is that the assignment operator is programmed to work
differently in the two languages.

Isn't that the case? Is the above true so far?

No. java doesn't have pointers, and java does not have the C++
reference syntax:

int num1 = 10;
int num2 = num1;
num2 = 5;

System.out.println(num1); //10
System.out.println(num2); //5

(and in Ruby, we call a method by "pass by value, the value being the
reference (pointer) to an object). and when the method returns
something, it returns a value, which is the reference to an object.) It
is very consistent all the way.

The key to understanding the difference between pass-by-value and
pass-by-reference, in any language, is understanding that there is no
difference in the passing mechanism. Something is always copied and
sent to the method. In pass-by-value, the value itself is copied and
sent to the method, so if you change the copy from inside the method, it
does not change the original value. In pass-by-reference, the address
is copied, so if you change the value at that address from inside the
method, then the value at that address is permanently changed, and after
the method ends, the change can still be observed.
In Ruby, we don't have the "alias
reference", right?

Let's see:

x = "hello"
y = x

y = "goodbye"
puts x, y #hello goodbye



def change_it(num)
num += 1
end

val = 5
change_it(val)
puts val #5

What is your conclusion?
 
D

David A. Black

Hi --

In Ruby, types that can (generally) fit into 32 bits are "immediate
types". These Fixnums and Floats are pass-by-value. All other types -
from String up - are pass by reference:

I'd describe it more as SpringFlowers did: pass by value, where the
value happens to be a reference. When you do this:

s = "string"
do_something(s)

you are passing s by its value, which is a reference to the string
object.


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

Robert Dober

Hi --



I'd describe it more as SpringFlowers did: pass by value, where the
value happens to be a reference.
Completely agruee with that. IIRC this discussion has been there quite
a while ago and general agreement was not reached on it.

<snip>
Robert
 
X

Xavier Noria

Completely agruee with that. IIRC this discussion has been there quite
a while ago and general agreement was not reached on it.

That's the way it is described in Java as well, Java is pass-by-
value, you pass references by value. C is pass-by-value as well, when
you modify something through a pointer you are passing a pointer by
value.

Perl on the other hand is pass-by-reference:

$ perl -wle '$a = 0; sub { $_[0] = 1 }->($a); print $a'
1

-- fxn
 
R

Robert Dober

Completely agruee with that. IIRC this discussion has been there quite
a while ago and general agreement was not reached on it.

That's the way it is described in Java as well, Java is pass-by-
value, you pass references by value. C is pass-by-value as well, when
you modify something through a pointer you are passing a pointer by
value.

Perl on the other hand is pass-by-reference:

$ perl -wle '$a = 0; sub { $_[0] = 1 }->($a); print $a'
hmm I am not sure about it,

perl -e '@x=qw{a};print $x[0]; sub{ @_ = qw{b}}->(@x); print $x[0]'

I guess the best thing one could say is

perl simulates pass by reference by passing one array by value.

Of course if one makes abstraction of @_...

Maybe not the best place to discuss this :(
Robert
 
D

David A. Black

Hi --

Completely agruee with that. IIRC this discussion has been there quite
a while ago and general agreement was not reached on it.

I don't think there's much ambiguity; when you do:

s = "string"

you're binding s to a reference to the object on the right.

Are you thinking of the discussion about whether or not it's
important/useful to note the distinction between references and
immediate values in variables?


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

Robert Dober

Hi --



I don't think there's much ambiguity; when you do:

s = "string"

you're binding s to a reference to the object on the right.

Are you thinking of the discussion about whether or not it's
important/useful to note the distinction between references and
immediate values in variables?
No rather this one
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/236400
seems I was completely confused that day between reference and value
:(, who knows why?
Cheers
Robert
 
S

SpringFlowers AutumnMoon

7stud said:
A C++ reference, which is a different type than a pointer in C++, is
actually implemented as a pointer behind the scenes. However, C++
references allow you to use a different syntax that doesn't require
dereferencing:

int x = 10;
int& r = x; //r becomes a pointer to the same address as x
r = 5;

cout<<x<<" "<<r<<endl; //5 5


I am starting to see what pointer and reference are and how they relate
to each other.

in the C era, a pointer *is* a reference. that's why when we have

int a = 10;
int *pi = &a;

and you can "dereference it":

*pi = 20;

Until when C++ comes along, then we have a new "reference":

int a = 10;
int i =& a; // or int i = &a; i am not sure about the syntax.
i = 20; // now both a and i are 20

so this type of reference is an implicit pointer... it points to a, but
you don't use the way in C (int *pi = &a) And when you use (i = 20),
it does the dereference silently. (*pi = 20;)

so a reference is new: a pointer but "looks like not a pointer".

come to think about it, in Java and Ruby, they are like that too.

a = Car.new

a doesn't look like a pointer, but it is actually a pointer.

we don't dereference it to get to the attributes like (*a).value = 10
or a->value = 10 but just use a.value = 10

So from this point on, a reference and a pointer are not the same... a
reference is a pointer "that doesn't look like a pointer."

they both points to something. but the syntax (or grammar) of usage
doesn't look like it is a pointer in the C era. a reference is an
"automatically dereferenced" pointer, shall we say? or an "implicit"
pointer, or "silent" pointer.
$a = 10;
$b =& $a; # now $b implicitly points to $a
$b = 20; # now $b implicitly points to $a, which is 20

$a = new Foo("hello"); # $a implicitly points to a Foo object
# the Foo object is 100 bytes,
# but $a is just 4 bytes

$b =& $a; # $b implicitly points to $a.
# $b is a pointer to pointer
# $b points to a four byte pointer, which is $a

$b = new Foo("ok"); # dereference $b and sets its content to
# a new pointer to another object Foo("ok")
# that is, $a points to Foo("ok") now
# $b still points to $a, which points to Foo("ok")

So now, when you print $b and $a, they are both Foo("ok")

So now gets back to Ruby, do we have something like the above

a = 10
b = ____lineA1_____
b = ____lineA2_____

and now b implicitly points to a, which implicitly points to something
else, not 10 any more.

similarly

a = Dog.new
b = ____lineB1_____
b = ____lineB2_____

and now b implicitly points to a, which implicitly points to something
else, not the original Dog.new object any more.

Do we have that in Ruby?
 
X

Xavier Noria

Perl on the other hand is pass-by-reference:

$ perl -wle '$a = 0; sub { $_[0] = 1 }->($a); print $a'
hmm I am not sure about it,

perl -e '@x=qw{a};print $x[0]; sub{ @_ = qw{b}}->(@x); print $x[0]'

I guess the best thing one could say is

perl simulates pass by reference by passing one array by value.

Of course if one makes abstraction of @_...

In Perl semantics when you write

print $a, %a;

print receives as many arguments as one plus twice the buckets in %a,
which gets flattened. You are not passing %a, you pass a handful of
scalars unrelated to %a from the subroutine's view.

Before you call a subroutine its arguments are first evaluated in
list context (except if a prototype says otherwise). Aliases (SV*s)
of the resulting list of scalars are then pushed onto the argument
stack and made available to the subroutine via @_. There's no array
involved in the call except as a metaphor so to speak.

That's considered pass-by-reference semantics and there's consensus
about it in the Perl community[*].

In Perl you emulate pass-by-value with idioms like this:

my ($foo, $bar) = @_;

-- fxn

[*] See pages 219-220 of the Camel Book, perlsub, section "Argument
stack" in perlhack, chapter "Perl Internals" in the Panther Book, ....
 
S

SpringFlowers AutumnMoon

SpringFlowers said:
a reference is an
"automatically dereferenced" pointer, shall we say? or an "implicit"
pointer, or "silent" pointer.

$a = 10;
$b =& $a; # now $b implicitly points to $a
$b = 20; # now $b implicitly points to $a, which is 20


just to clarify that when i write those code above, I am writing it as
PHP 5... i am having enough headache with PHP already... so can't talk
Perl until later...
 
R

Robert Dober

Perl on the other hand is pass-by-reference:

$ perl -wle '$a = 0; sub { $_[0] = 1 }->($a); print $a'
hmm I am not sure about it,

perl -e '@x=qw{a};print $x[0]; sub{ @_ = qw{b}}->(@x); print $x[0]'

I guess the best thing one could say is

perl simulates pass by reference by passing one array by value.

Of course if one makes abstraction of @_...

In Perl semantics when you write

print $a, %a;

print receives as many arguments as one plus twice the buckets in %a,
which gets flattened. You are not passing %a, you pass a handful of
scalars unrelated to %a from the subroutine's view.

Before you call a subroutine its arguments are first evaluated in
list context (except if a prototype says otherwise). Aliases (SV*s)
of the resulting list of scalars are then pushed onto the argument
stack and made available to the subroutine via @_. There's no array
involved in the call except as a metaphor so to speak.
But that depends on implementation only. I feel that much too often a
language's semantic is confused with the one of it's implementation.

It is exactly the metaphor you are referring to which is what we
should talk about; just imagine one would write a perl interpreter
that passes an array, it would have the same semantics thus still be
Perl.

This shows just another reason why having many Ruby implementations is so good.
That's considered pass-by-reference semantics and there's consensus
about it in the Perl community[*].
I am sure there is, however that does not count here ;)
Seriously speaking now:
You are completely right when you look at the problem from the
caller's side, that came to me after my post, sorry. It is call by
reference
Your parameter can contain a different object after the call, that is
pass by reference.

You are however wrong IMHO when looking at the problem from the
callees side, there is only one parameter which is @_. You have
accessed it in your example and when assigning to it the assignment is
not propagated to the actual parameters, that is clearly *not* call
by reference behavior.
or is my knowledge outdated maybe (I have learnt that 25years ago).
In Perl you emulate pass-by-value with idioms like this:

my ($foo, $bar) = @_;
Yup I remember that one, instead of my $foo = shift; my $bar = shift; ;)
Hmm I really cannot follow you, you just do a copy of the references
that is all.
-- fxn

[*] See pages 219-220 of the Camel Book, perlsub, section "Argument
stack" in perlhack, chapter "Perl Internals" in the Panther Book, ....
No need Xavier, we know perfectly how it works(1), we just cannot
agree what a parameter is - that is quite an intriguing discovery.

I feel that on this list my POV makes a little bit more sense than
yours, I mean we are talking to Rubiests after all.

(1) You know even how it is implemented which I do not, but that is irrelevant.Cheers
Robert
 
S

SpringFlowers AutumnMoon

7stud said:
In C++, references are sometimes called 'aliases'. But ruby also has
aliases:

x = "hello"
y = x

y[0] = "H"
puts x, y //Hello Hello

but does Ruby have something like:

x = "hello"
y = (whatever &*) x
y = "bye"

and both x, y will print out as "bye"?
 
X

Xavier Noria

You are however wrong IMHO when looking at the problem from the
callees side, there is only one parameter which is @_. You have
accessed it in your example and when assigning to it the assignment is
not propagated to the actual parameters, that is clearly *not* call
by reference behavior.
or is my knowledge outdated maybe (I have learnt that 25years ago).

Note that's your own interpretation, which does not coincide with the
semantics of Perl. In Perl @_ is not an argument, it is the mean by
which a function receives its arguments (versus named parameters).
That's the role of @_.

Since in Perl the arguments are the elements of @_, the fact that
assigning to $_[0] changes the value in the caller's shows Perl is
pass-by-reference. I explained a bit what happens under the hood to
depict aliases are actually passed through the stack. But to justify
pass-by-reference (eg in the Camel Book) you don't refer to the
implementation, you assert it does because of the way it works,
because of the semantics.

-- fxn
 
R

Robert Dober

You are however wrong IMHO when looking at the problem from the
callees side, there is only one parameter which is @_. You have
accessed it in your example and when assigning to it the assignment is
not propagated to the actual parameters, that is clearly *not* call
by reference behavior.
or is my knowledge outdated maybe (I have learnt that 25years ago).

Note that's your own interpretation, which does not coincide with the
semantics of Perl. In Perl @_ is not an argument, it is the mean by
which a function receives its arguments (versus named parameters).
That's the role of @_.

Since in Perl the arguments are the elements of @_, the fact that
assigning to $_[0] changes the value in the caller's shows Perl is
pass-by-reference. I explained a bit what happens under the hood to
depict aliases are actually passed through the stack. But to justify
pass-by-reference (eg in the Camel Book) you don't refer to the
implementation, you assert it does because of the way it works,
because of the semantics.

-- fxn

Well I have bravely spoken up against the Perl expert, to continue
doing so would be probably impolite and/or stupid.
I also refrain from asking questions as this list is not the right
place to do so, but I have to admit that I am quite puzzled by these
statements.

Anyway by looking at the semantics of a perl sub call from outside it
is like pass by reference and looking at the inside is not at all in
the scope of this list ....

Cheers
Robert
 
G

Guest

7stud said:
In C++, references are sometimes called 'aliases'. But ruby also has
aliases:
x = "hello"
y = x
y[0] = "H"
puts x, y //Hello Hello

but does Ruby have something like:

x = "hello"
y = (whatever &*) x
y = "bye"

and both x, y will print out as "bye"?

In my opinion, the references we called in ruby, java are actually
pointers which needn't dereference. That means when a variable in
ruby, java is used as a left value, it works like a pointer, when as a
right value, it dereference automatically.

In java, when we say:

String s = "abc";

what the system actually does is:
1.create an anonymous object "abc".
2.create an varible(reference, actually a pointer) s.
3.let s point to abc;

now we can return to the two different case:
first:
x = "hello"
y = x
y = "bye"
puts x, y //hello, bye

in this case, what the system does is
1.create "hello";
2.create x;
3.let x point to "hello";
4.create y;
5.let y point to what x points to (right value, x is dereferenced
automatically);
6.create "bye";
7.let y point to "bye";
8.print x, y (right value, x,y are dereferenced automatically);
In this case the third sentence changed the object which y points to.
so at last, x,y are different.

and the second case:
x = "hello"
y = x
y[0] = "H"
puts x, y //Hello Hello

we can see in this case, the object which y point to doesn't be
changed. the third sentence just change the first charactor of the
"hello" object, and x,y point to the same object.

so, the second example doesn't means ruby has an "alias" machanism
like c++, ruby's machanism is ruby's not c++'s.

when passing parameters, ruby, java has only one sementics. it is
"dereference automatically and pass a copy". c/c++ has two way "pass
by value" and "pass by reference".

in a word, in ruby, java, the sementics is not "value" or "reference"
in c++, but something between them like what i say above.
 
R

Rick DeNatale

Hi --



I'd describe it more as SpringFlowers did: pass by value, where the
value happens to be a reference. When you do this:

s = "string"
do_something(s)

you are passing s by its value, which is a reference to the string
object.

Long ago I read a forgotten article which made the distinction between:

pass by value
pass by reference
and
pass by object reference

Pass by value copies some state held in a variable, the subroutine can
change that state without affecting the original variable.

Pass by reference passes the address of the VARIABLE, and the
subroutine can change the state held in the variable.

Pass by object reference passes a reference to the object, you can't
change the original variable, but you can change the object by
invoking methods which mutate the object.

In pure object-oriented languages like Ruby, pass by object reference
is the rule. Assignment has similar semantics.

Thinking of it this way has the advantage that we can treat object
references a opaque. The fact that in a given implementation a
reference to a particular object might also be the representation of
it's state (i.e. immediate objects) becomes irrelevant. If we pass or
assign a FixNum for instance, the fact that we can't change it is
because Fixnums have no mutating methods, in fact it's a prerequisite
that only objects with no mutating methods can have an immediate
representation.

And by the way, SpringFlower, Floats are NOT immediate objects in Ruby.
 

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,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top