what's an object?

T

timr

One other point. A local variable is not an object and never is -

I think that's too general and confusing, at least to me.
def m
  a = [1,2,3]
  p a.is_a?(Object)
  end => nil
m

true
=> true

Is there more insight behind that statement? Or am I missing something
fundamental?

Thanks,
Ammar

When you ask object#is.a?(Class) you are asking if the Class is part
of the ancestry of the object. So you ask an array if it inherits
directly or indirectly from the Object class, and the answer is yes.
Here is a demo:=> [New, String, Enumerable, Comparable, Object, Kernel]

But there is a distinction between inheriting from the Object class
and being an object. A better demonstration that the object like the
variable a points to in your example, is an instantiated object is to
ask it if it has an object_id--and it will. So the answer agrees with
the is_a? result, but the questions are asking very different things.
Tim
 
Z

zuerrong

Hi Brian,

I just tested what you said, the result is opposite, a is changed.

irb(main):026:0> def foo(x)
irb(main):027:1> puts x.object_id
irb(main):028:1> x << "world"
irb(main):029:1> puts x
irb(main):030:1> puts x.object_id
irb(main):031:1> end
=3D> nil

irb(main):033:0> a=3D"nice"
=3D> "nice"

irb(main):034:0> a.object_id
=3D> 79554920

irb(main):035:0> foo(a)
79554920
niceworld
79554920
=3D> nil

irb(main):036:0> a
=3D> "niceworld"


2010/11/11 Brian Candler said:
def foo(x)
=C2=A0x << " world"
end

a =3D "hello"
foo(a)

a is passed by value, so the method call foo(a) can never affect the
value of a

--=20
Kind regards,
=C2=A0 =C2=A0 =C2=A0Zuer (=E7=A5=96=E5=84=BF)
 
T

timr

One other point. A local variable is not an object and never is -

I think that's too general and confusing, at least to me.
def m
  a = [1,2,3]
  p a.is_a?(Object)
  end => nil
m

true
=> true

Is there more insight behind that statement? Or am I missing something
fundamental?

Thanks,
Ammar

Hi Ammar,
I do think the code means something different than you are
interpreting it to mean.

obj.is_a?(Object) asks if Object is listed in the ancestors of obj. It
is another way of saying obj.class.ancestors.include?(Object)

Everything you can send a message to in ruby is a descendent of
Object, so it will always be true, er, I predict. However, when you
ask a local variable (which is really a pointer to, in your case, an
instance of Array) you are asking is Object listed in the ancestors of
the Array class? It doesn't ask if a variable considers itself an
instantiated object.
Tim
 
J

John Mair

@josh,

It's a question of the mental model, but to my memory even Matz's mental
model does not correspond to yours - i remember seeing a presentation
where he explicitly said that methods were not objects, I can find it
soon hopefully and link it here.

Nonetheless, the book "The Ruby Programming Language" which was
co-written
by Matz has this to say on the matter:

"Methods are a fundamental part of Ruby's syntax, but they are not
values that Ruby programs can operate on. That is, Ruby's methods are
not objects in the way that strings, numbers, and arrays are. It is
possible, however, to obtain a Method object that represents a given
method, and we can invoke methods indirectly through Method objects."

Also see this thread: http://www.ruby-forum.com/topic/190057

One of the rationale given in the above thread is that the object ids
are different each time you call the 'method' method:

method:)puts).object_id != method:)puts).object_id

John



Josh Cheek wrote in post #960762:
Disclaimer: I seem to be in a crabby mood this morning. I went back over
it
(twice) and tried to take out things that were unfriendly, sorry if I
missed
anything.

/* obtain the Function structure which wrap the function *func* */
Function *func_obj = obtain_Function( func );

That isn't what you do in Ruby. In Ruby, you don't pass the function (or
function pointer in this case), you pass a String or Symbol.

So this example is not consistent with what Ruby does, doesn't have any
explanatory power (that I can see, though I don't write C extensions),
and
makes everything more complicated.

Here is an alternative model: In Ruby, everything is an object. Methods
are
objects, hence the method class.
http://ruby-doc.org/core/classes/Method.html But you can't directly
access
them, because Ruby doesn't make you use parentheses. So trying to access
the
method directly looks to the interpreter like you want to invoke the
method,
since that is pretty much always what you want to do. But every now and
then, you want to actually get the method, and so Ruby gives you a
getter
method that knows how to do that, and it's aptly named "method".

In C, that looks something like

#include <stdio.h>
#include <string.h>

typedef struct {
char* name;
int (*pointer)( int arg );
} Method;

int twice( int arg ) { return arg * 2; }
int thrice( int arg ) { return arg * 3; }

Method internal_mlist[] = {
{ "twice" , twice },
{ "thrice" , thrice },
};

Method* method( char* name ) {
int i;
for( i = 0 ; i < sizeof(internal_mlist)/sizeof(Method) ; ++i )
if( !strcmp( internal_mlist.name , name ) )
return &internal_mlist;
return NULL;
}

int main( ) {
method("twice");
method("thrice");
return 0;
}

For a longer version that is more in line with my mental model
https://gist.github.com/672665

I think that Ruby users need not know how a Method object wraps a
method, but they should know the fact that a Method object wraps a
method and a method is not a object.
Why? Is that even a Ruby thing? It seems so out of place to me that I
would
assume it is an MRI implementation detail. Do the other Rubies do it
that
way? If so, is it just for efficiency where they are all objects as soon
as
we need them to be, but keep it lazy and don't bother turning them into
objects until such time as we know we need it?

You guys were talking about a spec earlier, the site is apparently down
right now, but I downloaded the source from github (
https://github.com/rubyspec/rubyspec), trying to find something on this.
Maybe I'm not looking in the right spot (I searched for /\.method[^_s]/)
but
I didn't see anything like this in there.



Yes. It's important when you compare "pass by value" or "pass by
reference" in other languages. In ruby, everything is "pass by value",
and each value is a reference to an object - even integers.
I think we settled on the phrase "object reference" last time this came
up.
 
J

Josh Cheek

1.method('+') is not the same as 1.+, so your example does not prove + is
a method. The object ID you get with 1.method('+').object_id is actually
the object ID of the object that is returned by the method "method" when
it is passed an argument of the string "+". That is not the same thing
as an object ID for the + method itself.

Here's a thought experiment for you:

If + is an object, and 1.method('+') returns that object so that you can
get its object ID with 1.method('+').object_id, this should work:


Fire up irb and try it, now. It doesn't work.

Instead, if you want to use it, you need to do this:


That's because a "method object" is not a method; it is a proc that wraps
the method and its scope context.

Why should you be able to do foo(3) ? That would require completely changin=
g
the way Ruby is interpreted. I suspect this idea comes from less OO
languages like JavaScript and Python. In Ruby, you can't do that, because i=
f
foo is the object, then you interact with it by invoking methods. (3) isn't
a method, it's an argument, so we need to define a method that will invoke
our method object. So we define #call and use .call(3)

The fact that you have to send it a message shows it is an object, which is
easy to see, since at this point, foo _is_ an object. It is an instance of
Method.

I think it would be much more convincing to me that there is any merit to
this model if you could show me, for example, how you interact with it in
its non-object form.


It's a question of the mental model, but to my memory even Matz's mental
model does not correspond to yours - i remember seeing a presentation
where he explicitly said that methods were not objects, I can find it
soon hopefully and link it here.

Nonetheless, the book "The Ruby Programming Language" which was
co-written
by Matz has this to say on the matter:

"Methods are a fundamental part of Ruby's syntax, but they are not
values that Ruby programs can operate on. That is, Ruby's methods are
not objects in the way that strings, numbers, and arrays are. It is
possible, however, to obtain a Method object that represents a given
method, and we can invoke methods indirectly through Method objects."
Hi, John. I suspect that Matz' mental model views methods like this because
he is implementing MRI. For him, this is a necessary model. Aside from
object_id, I can't think of any situation outside of the C code where this
would ever be a useful way of thinking. I would expect that most of the tim=
e
it will just make it more difficult for you to reason about your code,
because your mental model is more complicated due to having have one more
exception for where Ruby behaves unexpectedly that you have to reason
through.

Right after Matz' quote you gave, he says "Blocks, like methods, are not
objects that Ruby can manipulate." But on this topic, I am very much with
Yehuda Katz who says

"In a number of places, it is possible to imbue Ruby semantics with mental
models that reflect the actual Ruby implementation, or the fact that it=92s
possible to imagine that a Ruby object only springs into existence when it
is asked for.

However, these mental models require that Ruby programmers add non-objects
to the semantics of Ruby, and requiring contortions to explain away Ruby=92=
s
own efforts to hide these internals from the higher-level constructs of the
language. For instance, while Ruby internally wraps and unwraps Procs when
passing them to methods, it makes sure that the Proc object attached to a
block is always the same, in an effort to hide the internal details from
programmers.

As a result, explaining Ruby=92s semantics in terms of these internals
requires contortions and new constructs that are not natively part of Ruby=
=92s
object model, and those explanations should be avoided."(
http://yehudakatz.com/2010/02/25/rubys-implementation-does-not-define-its-s=
emantics/
)


That is exactly what I feel is happening here.
 
X

Xavier Noria

Hi Brian,

I just tested what you said, the result is opposite, a is changed.

Point is a holds a reference, and that one can't be changed. You can
change the state of the object it points to if it is mutable, but the
string object is the same when the method returns because Ruby has
pass by value semantics.

I wrote a post about this a while back:

Ruby, C, and Java are pass-by-value, Perl is pass-by-reference
http://advogato.org/person/fxn/diary/534.html

Sent from my iPad
 
J

John Mair

@Josh,

I agree with Yehuda too. But I do not feel the case of Method
objects/methods is analogous to the case of blocks/procs. The
fundamental reason is that a very crucial point of Yehuda's argument is
that when you on-pass the block it has the same object_id; in fact in
Yehuda's article this point is mentioned multiple times culiminating in
this statement:

"You can tell that blocks are not being semantically wrapped and
unwrapped
because blocks passed along via & share the same object_id across
methods."

This semantic wrapping/unwrapping on the other hand is EXACTLY what's
happening in the case of methods and method objects. In other words,
what is happening with methods/method objects is precisely what Yehuda
was arguing was *not* happening with blocks/procs.

Yehuda's argument *would* apply to methods/method objects if the
object_id remained the same across multiple calls to the method method.
Read what he wrote again, the persistent object_id is a big part of his
argument.

To try to maintain the mental model that a method is really an object is
actually impossible if the object keeps changing ;)

It is not impossible in the case of blocks/procs however, as the
object_id remains the same.

One last example to drive it home:

method:)puts).instance_variable_set:)@hello, :hello)
method:)puts).instance_variagle_get:)@hello) #=> nil

John
 
R

Robert Klemme

You can even do

irb(main):001:0> foo =3D 1.method '+'
=3D> #<Method: Fixnum#+>
irb(main):002:0> foo[3]
=3D> 4

which is pretty close to foo(3).

Exactly.

Kind regards

robert


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

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

Point is a holds a reference, and that one can't be changed. You can
change the state of the object it points to if it is mutable, but the
string object is the same when the method returns because Ruby has
pass by value semantics.

I wrote a post about this a while back:

Ruby, C, and Java are pass-by-value, Perl is pass-by-reference
http://advogato.org/person/fxn/diary/534.html

Sent from my iPad
Can we just call it "pass by object reference". Calling it "pass by value"
is so confusing, because in the code below, it sounds like you are talking
about the first function call when you are actually talking about the
second. And quite frankly, I think some people swap these definitions out
with each other. In your blog, your picture of pass by reference is actually
what I am calling pass by object reference, which you call pass by value (so
you give that as an example of not being what Ruby does, when it actually
is). It makes the entire discussion extremely difficult since different
things have the same name, and people's positions are shifting all the time.


#include <stdio.h>

typedef struct { int value; } Number;

void pass_by_value( Number number ) {
printf("Pass by value: %d\n" , number.value );
}

void pass_by_object_reference( Number *number ) {
printf("Pass by object reference: %d\n" , number->value );
}

void pass_by_reference( Number **number ) {
printf("Pass by reference: %d\n" , (*number)->value );
}

int main( ) {
Number object = { 12 };
Number* variable = &object; /* in Ruby you interact with objects through
variables that reference them */
pass_by_value(*variable);
pass_by_object_reference(variable);
pass_by_reference(&variable);
return 0;
}


@Josh,

I agree with Yehuda too. But I do not feel the case of Method
objects/methods is analogous to the case of blocks/procs. The
fundamental reason is that a very crucial point of Yehuda's argument is
that when you on-pass the block it has the same object_id; in fact in
Yehuda's article this point is mentioned multiple times culiminating in
this statement:

"You can tell that blocks are not being semantically wrapped and
unwrapped
because blocks passed along via & share the same object_id across
methods."

This semantic wrapping/unwrapping on the other hand is EXACTLY what's
happening in the case of methods and method objects. In other words,
what is happening with methods/method objects is precisely what Yehuda
was arguing was *not* happening with blocks/procs.

Yehuda's argument *would* apply to methods/method objects if the
object_id remained the same across multiple calls to the method method.
Read what he wrote again, the persistent object_id is a big part of his
argument.

To try to maintain the mental model that a method is really an object is
actually impossible if the object keeps changing ;)

It is not impossible in the case of blocks/procs however, as the
object_id remains the same.

One last example to drive it home:

method:)puts).instance_variable_set:)@hello, :hello)
method:)puts).instance_variagle_get:)@hello) #=> nil

John
Okay. I guess I will agree to disagree. For me, that is a lot of exceptional
cases to add to my understanding of the language just to explain a different
object id (which almost feels like an oversight to me, but I checked, and
the spec code doesn't address that), and I am going to opt for the elegant
model where everything is an object until such time as it becomes a
hindrance. If you don't wish to do that, I won't tell you to, though I don't
think it's a good idea to teach it to newcomers, poor Eva's head must be
spinning :p
 
X

Xavier Noria

Can we just call it "pass by object reference". Calling it "pass by value=
"

I see no need. The stuff is pretty simple. Variables in Ruby and Java
hold references, their spec say that, it is not a mental model of mine.
(In the case of Java they can also store primitive values, you know.)

References are opaque, but it is known that whatever they are, that's
what variables hold. And the content of the variable is copied
when there's a method call.
void pass_by_object_reference( Number *number ) {
=C2=A0printf("Pass by object reference: %d\n" , number->value );
}

In the case of C there's no room for interpretation either. And it is
even more transparent than in Ruby because pointers are data types. So
that number parameter holds a data value which is a pointer, that one
isn't even opaque.

When the function is invoked the pointer is *copied*, that is, an integer
value is copied and linked to a local variable. The exact same thing
happens if the parameter is int i.

The pointer value is copied into the number variable (pass by value).
You can be certain the caller sees the exact same pointer when
the function call returns.
 
Y

Y. NOBUOKA

Hi, Josh
That isn't what you do in Ruby. In Ruby, you don't pass the function (or
function pointer in this case), you pass a String or Symbol.

I wanted to show the simple example, so I used the function pointer.
My example, however, was not good. Sorry.
Here is an alternative model: In Ruby, everything is an object. Methods a= re
objects, hence the method class.
http://ruby-doc.org/core/classes/Method.html But you can't directly acces= s
them, because Ruby doesn't make you use parentheses. So trying to access = the
method directly looks to the interpreter like you want to invoke the meth= od,
since that is pretty much always what you want to do. But every now and
then, you want to actually get the method, and so Ruby gives you a getter
method that knows how to do that, and it's aptly named "method".

We can think a method is an object but we can't touch it, as you said.
Then, why do we need to think that it is an object? We need not
consider a method as an object, because we cannot access the object
which represents the specific method even if a method is an object.

If you think that the Method object represents the specific method
directly, the idea is not good. The Method object knows not only the
method but also the receiver, so there are many different Method
objects that refer to the same method. Please see the following
example.

---
class C
# the method *meth* is defined in a class *C*
def meth
puts "aaa"
end
end
c1 =3D C.new

# we can get the Method object which refers to the method C#meth
meth_obj1 =3D c1.method :meth
# this object knows the receiver
meth_obj1.receiver =3D=3D c1 #=3D> true

# other Method object which refers to the same method
meth_obj2 =3D C.new.method :meth
# both meth_obj1 and meth_obj2 refer to the method C#meth,
# but these objects is not equal
meth_obj1 =3D=3D meth_obj2 #=3D> false
---

In the example, we can see these Method objects don't represent the
method C#meth directly. Then, how do we obtain the object which
represents the method C#meth directly? No, we can't. There is no way.

That is why we cannot identify the Method object with the specific method.
Why? Is that even a Ruby thing? It seems so out of place to me that I wou= ld
assume it is an MRI implementation detail. Do the other Rubies do it that
way? If so, is it just for efficiency where they are all objects as soon = as
we need them to be, but keep it lazy and don't bother turning them into
objects until such time as we know we need it?

Yes. It is a Ruby's concept that a method is not an object.

Please see Ruby Draft Specification:
http://www.ipa.go.jp/software/open/ossc/english/ruby/ruby_draft_specificati=
on.html
Although this document is still draft version, it is a good document
for us to learn the Ruby's fundamental concepts. In sec.6.3, they
write about a method. Quoting from it:

"A method is a procedure which, when invoked on an object, performs a
set of computations on
10 the object. A method itself is not an object."

Using any Ruby implementation, Ruby users should think a method itself
is not an object.

--=20
NOBUOKA Yuya
 
Y

Y. NOBUOKA

The first question is: "What is an object?"

Ruby Draft Specification answers the question, also. Sec.6.1 on the
document says:

---
6.1 Objects

An object has states and a behavior. An object has a set of bindings
of instance variables (see 6.2.2) as one of its states. Besides the
set of bindings of instance variables, an object can have some
attributes as its states, depending on the class of the object. The
behavior of an object is defined by a set of methods (see 6.3) which
can be invoked on that object. A method is defined in a class, a
singleton class, or a module (see 6.5).

Every value directly manipulated by a program is an object. For
example, all of the following values are objects:

-=88 A value which is referred to by a variable (see 6.2);
-=88 A value which is passed to a method as an argument;
=88 - A value which is returned by a method;
-=88 A value which is returned as the result of evaluating an
expression (see Clause 11), a statement (see Clause 12), a
compound-statement (see 10.2), or a program (see 10.1).

Other values are not objects, unless explicitly specified as objects.
---

Regards,

2010/11/11 Eva said:
I'm also switching from perl and php.
I'm not sure in ruby what's an object.
It seems each instance of a class is an object, is it?

Thanks.

--=20
NOBUOKA Yuya
 
J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

When the function is invoked the pointer is *copied*, that is, an integer
value is copied and linked to a local variable. The exact same thing
happens if the parameter is int i.

The exact same thing also happens with a reference (at least in C++, I don't
know anything about Perl).

The pointer value is copied into the number variable (pass by value).
You can be certain the caller sees the exact same pointer when
the function call returns.
Please re-read your blog with this in mind, since what you right here in
this quote are calling "pass by value" you, in your blog, call
"pass-by-reference".

http://img193.imageshack.us/img193/6480/refl.jpg

In the example, we can see these Method objects don't represent the
method C#meth directly. Then, how do we obtain the object which
represents the method C#meth directly? No, we can't. There is no way.
cmeth1 = meth_obj1.unbind
cmeth2 = meth_obj2.unbind

cmeth1 == cmeth2 # => true
cmeth1 == C.instance_method('meth') # => true
cmeth2 == C.instance_method('meth') # => true
C.instance_method('meth') == C.instance_method('meth') # => true


Yes. It is a Ruby's concept that a method is not an object.

Please see Ruby Draft Specification:

http://www.ipa.go.jp/software/open/ossc/english/ruby/ruby_draft_specification.html
Although this document is still draft version, it is a good document
for us to learn the Ruby's fundamental concepts. In sec.6.3, they
write about a method. Quoting from it:

"A method is a procedure which, when invoked on an object, performs a
set of computations on
10 the object. A method itself is not an object."
I will concede that you have a spec which says that a method is not an
object. However, I do so with reserve, because this same spec, in this same
paragraph it says "A method has one or more (when aliased) names associated
with it. An association between a name and a method is called a method
binding . When a name N is bound to a method M, N is called the name of the
binding, and M is called the value of the binding. A name bound to a method
is called the method name . A method can be invoked on an object by
specifying one of its names. The object on which the method is invoked is
called the receiver of the method invocation."

Yet, UnboundMethods still have names

String.instance_method("upcase") # => #<UnboundMethod: String#upcase>
String.instance_method("upcase").name # => :upcase
 
X

Xavier Noria

The exact same thing also happens with a reference (at least in C++, I don't
know anything about Perl).


Please re-read your blog with this in mind, since what you right here in
this quote are calling "pass by value" you, in your blog, call
"pass-by-reference".

http://img193.imageshack.us/img193/6480/refl.jpg

No, no. If Ruby did what the diagram shows the program

def m(b)
b = Object.new
p b.object_id
end

a = Object.new
m(a)
p a.object_id

would print the same number because a and b would be pointing to the
same storage area. They aren't.
 
R

Robert Dober

No, no. If Ruby did what the diagram shows the program

=A0 =A0def m(b)
=A0 =A0 =A0b =3D Object.new
=A0 =A0 =A0p b.object_id
=A0 =A0end

=A0 =A0a =3D Object.new
=A0 =A0m(a)
=A0 =A0p a.object_id

would print the same number because a and b would be pointing to the
same storage area. They aren't.
Are you sure Xavier?
I am afraid that in

def x b
b =3D ...
you brake the link as shown in the diagram (somehow as having a local
variable shadowing the param)

because if you made

def x b
b << "hello"

the diagram seems correct, or is it I who misses something here?

Cheers
R.


--=20
The 1,000,000th fibonacci number contains '42' 2039 times; that is
almost 30 occurrences more than expected (208988 digits).
N.B. The 42nd fibonacci number does not contain '1000000' that is
almost the expected 3.0e-06 times.
 
J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

No, no. If Ruby did what the diagram shows the program

def m(b)
b = Object.new
p b.object_id
end

a = Object.new
m(a)
p a.object_id

would print the same number because a and b would be pointing to the
same storage area. They aren't.
How can b change what a points to when, according to your own diagram, b
does not have any reference to a?

Here is the diagram which shows pass-by-reference and
pass-by-object-reference http://img405.imageshack.us/img405/3699/ref1.jpg

And I think your confusion itself is adequate justification for Ruby's style
to deserve its own name "pass by object reference"

Also, I would appreciate if more prominent Rubyists would weigh in on this.
So far, I am disagreeing with everyone in this thread. I would like to know
what the people that I have learned to respect think. I just disagree,
because those on the other side seem so conspicuously wrong. But the number
of people on that side seems disconcerting. I would like an objective
measure in the form of people whose conclusions I can't roll my eyes at.
 
X

Xavier Noria

Are you sure Xavier?
I am afraid that in

def x b
=C2=A0b =3D ...
you brake the link as shown in the diagram (somehow as having a local
variable shadowing the param)

because if you made

def x b
=C2=A0b << "hello"

the diagram seems correct, or is it I who misses something here?

Not sure I follow.

Variables can't store objects, that's guaranteed by the Ruby spec,
they only store references.

There, b holds a reference to a string. Strings are mutable in Ruby,
and << appends in place. The b variable holds a reference to the same
object stored in the variable of the caller. This is no different than
passing a user instance and calling user.name=3D inside the method.

Let's suppose for a moment that the object_id serves as reference, as
if it was a pointer. Let's imagine "" has object id 2158937800. The
diagram is:

a -> 2158937800 -> ""
b -> 2158937800 -> ""

Note that a and b store the same reference value, but they are separate.

If we assign a new string "b" to b inside the method with object id
2158934000 the diagram becomes

a -> 2158937800 -> ""
b -> 2158934000 -> "b"

because a and b store different values.
 
X

Xavier Noria

=C2=A0 =C2=A0a -> 2158937800 -> ""
=C2=A0 =C2=A0b -> 2158937800 -> ""

Sorry, the rightmost arrows should point to the same unique "" here.
Couldn't do proper ascii diagrams with variable-width font.

In the next diagram two arrows are correct.
 
X

Xavier Noria

How can b change what a points to when, according to your own diagram, b
does not have any reference to a?

Here is the diagram which shows pass-by-reference and
pass-by-object-reference http://img405.imageshack.us/img405/3699/ref1.jpg

And I think your confusion itself is adequate justification for Ruby's st= yle
to deserve its own name "pass by object reference"

Also, I would appreciate if more prominent Rubyists would weigh in on thi= s.
So far, I am disagreeing with everyone in this thread. I would like to kn= ow
what the people that I have learned to respect think. I just disagree,
because those on the other side seem so conspicuously wrong. But the numb= er
of people on that side seems disconcerting. I would like an objective
measure in the form of people whose conclusions I can't roll my eyes at.

The Ruby spec says in section 6.2.1.

"A variable is denoted by a name, and refers to an object, which is
called the value of the variable. A variable itself is not an object.
While a variable can refer to only one object at a time, an object can
be referred to by more than one variable at a time."

Then in section 13.3.3 you'll see that the spec says that you create
local variable bindings from the arguments. For example, regarding
mandatory parameters:

"If Pi is a mandatory parameter, let n be the mandatory-parameter. If
Pi is an optional parameter, let n be the optional-parameter-name.
Create a variable binding with name n and value Ai in Sb."

I admit that the term "reference" is not used. I admit also that the
section about method invocation does not explicitly say "copy" as the
JLS does. But a posteriori the semantics are pass by value.

The binding is local, the variables are not aliases bound to the same
storage area. When you assign to the local variable, the caller is
unaffected. Being able to change the state of a mutable object is
unrelated to call semantics.

Conceptually my diagram lacks the middle boxes that represent the
indirection between the variable and the objects themselves.

I guess MRI binds VALUEs to variables, but I am only talking about
semantics, about how this works conceptually, not about what a
particular implementation does.
 
R

Robert Dober

=A0 =A0a -> 2158937800 -> ""
=A0 =A0b -> 2158937800 -> ""

Note that a and b store the same reference value, but they are separate.

If we assign a new string "b" to b inside the method with object id
2158934000 the diagram becomes

=A0 =A0a -> 2158937800 -> ""
=A0 =A0b -> 2158934000 -> "b"

because a and b store different values.
That's actually what I meant: When passing the parameter the diagram
is correct. I do not see any reason why you claim the diagram
incorrect - for what the param passing semantics concerns - only
because Ruby gives you the freedom to reassign the param inside the
body of the method.
I wanted to express that this manipulation should not be used to prove
the correctness or incorectness of a given param passing model.
Clearer?

Cheers
R.


--=20
The 1,000,000th fibonacci number contains '42' 2039 times; that is
almost 30 occurrences more than expected (208988 digits).
N.B. The 42nd fibonacci number does not contain '1000000' that is
almost the expected 3.0e-06 times.
 

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,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top