Value by reference

The distinction is not between clonable objects and non-clonable
objects, AFAICT. It's between immediate and value objects in this
particular case, but the real problem is that you're exhibiting a
confusion between variables and objects.

-austin

···

On Thu, 20 Jan 2005 02:14:59 +0900, Mohammad Khan <mkhan@lextranet.com> wrote:

I understand that. But what about scenario 2? Scenario 2 is not
acting as scenario 1, is it because scenario 2 gets object rather
than variable? Or, Scenario 2 gets clonable object while scenario
1 not? Thanks, Florian.

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

Yes, and no.

  a = 1
  b = 2
  c = 3

The values 1, 2, and 3 are objects. a, b, and c are not objects.

  def foo(a, b, c)
  end

In #foo, a, b, and c are most definitely NOT objects -- they're
variables that (will) contain references to objects.

In Ruby, variables are names, not memory slots.

  a = b = 1

The real memory slot is more or less identified by Object#id. The
variable is just a convenience label for that object. Change the
object that the label is pointing to, and you just change the
position of the label's name. You're not actually changing the
memory location involved.

What you're after is something you shouldn't do with Ruby. Rethink
your design.

-austin

···

On Thu, 20 Jan 2005 02:17:19 +0900, Mohammad Khan <mkhan@lextranet.com> wrote:

a, b, and c are not objects. They're variables.

Isn't everything *object* in Ruby?
Now you know, what I am after ?!

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

Hi --

Florian Gross wrote:

See my earlier posting about the lambda { } and Variable[:name] ways of doing this.

Sorry, but I can't believe anybody would actually want to use the lambda styles as proposed. They are ugly and obscure.

Ruby itself just treats variables as names for Objects. You can't really refer to a variable itself, you can only refer to the Object it is a name for. That's a surprisingly simple and non-confusing model.

Judging by the frequency that this issue is discussed, it's more confusing than you suggest.

Then again, I've found that when people get confused by things in
Ruby, it's very often because Ruby is simpler and less cluttered than
they expect it to be. My favorite example of this is the singleton
class model.

A typical programmers expects call-by-reference to work one way, and Ruby works differently. Extra confusion results because this difference is masked by using self-updating methods, but it always fails for immediate objects, and it eventually fails in a surprising way for non-immediate objects. I call it surprising because a typical programmer does not expect the assignment operator to destroy call-by-reference, but that is exactly what happens.

def inc1(a, i); a += i; end
def inc2(a, i); a = a + i; end

To the naive Ruby programmer, inc1 and inc2 seem to be equivalent, but Ruby gurus just shake their heads and sigh while they explain, yet again, that there is a difference. Why is this considered a good thing? :slight_smile:

We must know different Ruby gurus -- the ones I know are remarkably
gracious, even enthusiastic, about explaining things :slight_smile:

In any case, I believe the two things in your example are actually
equivalent. My understanding is that Ruby always expands:

    x += y

to

    x = x + y

I don't think there are any cases where it makes any difference which
one you use, at least as far as I can remember.

As for confusion, typical programmers, etc.: I don't think there's as
much of the "princess and the pea" syndrome among programmers as one
might think -- most people seem to be fairly adventurous and
thick-skinned -- and people certainly have to rise above that if they
want to explore more than a rather small number of programming
technologies. Besides, languages with other models exist already.
Ruby also exists, and there's no more reason for Ruby to converge on
the model of some other language than for some other language to
converge on Ruby. (Maybe even less :slight_smile: Away with the Ruby
inferiority complex! :slight_smile:

Ruby does *not* support call-by-reference, in the traditional sense of the term. Instead, it is strictly call-by-value, and formal paremeters are copies of references from the calling scope.

This is the key to it, in my opinion. Every "value" in Ruby is a
reference, and every reference to an object is the same distance from
the object as every other reference to that object (as in: a =
Object.new; b = a; a and b are now equivalent with respect to
their distance from the object).

David

···

On Wed, 19 Jan 2005, Glenn Parker wrote:

--
David A. Black
dblack@wobblini.net

sorry if this offends, but there is no less blunt way to say it.
if anyone need it. they've gone wrong already.
the solution: design

alex

···

On Jan 19, 2005, at 3:06 PM, trans. wrote:

Right. I'm not suggesting that Ruby change this. I'm just wondering if
might be possible to add an extra feature that would allow for the
alternate when passing arguments through methods.

Florian Gross wrote:

See my earlier posting about the lambda { } and Variable[:name]
ways of doing this.

Sorry, but I can't believe anybody would actually want to use the
lambda styles as proposed. They are ugly and obscure.

The Variable method is useful; I agree about lambda for this bit.

Ruby itself just treats variables as names for Objects. You can't
really refer to a variable itself, you can only refer to the
Object it is a name for. That's a surprisingly simple and
non-confusing model.

Judging by the frequency that this issue is discussed, it's more
confusing than you suggest.

I disagree. The problem is when it's explained that everything is a
reference. The best description I've seen for this was said a month
ago or so: Ruby's calling semantics are pass by value, but the value
passed is a reference to an object. People *understand* pass by
value and people *understand* pass by reference, but only after it's
been explained to them. This is no different; you have to learn the
calling semantics. It's pass-reference-by-value. Don't think too
much about variables -- they're just names, not memory blocks.

A typical programmers expects call-by-reference to work one way,
and Ruby works differently. Extra confusion results because this
difference is masked by using self-updating methods, but it always
fails for immediate objects, and it eventually fails in a
surprising way for non-immediate objects. I call it surprising
because a typical programmer does not expect the assignment
operator to destroy call-by-reference, but that is exactly what
happens.

This has been a situation where people are applying the concepts of
C/C++ and similar languages (where variables are slots in memory) to
Ruby (where variables are simply labels for object references).
Variables are programmers' tools in Ruby; nothing more, nothing
less.

def inc1(a, i); a += i; end
def inc2(a, i); a = a + i; end

To the naive Ruby programmer, inc1 and inc2 seem to be equivalent,
but Ruby gurus just shake their heads and sigh while they explain,
yet again, that there is a difference. Why is this considered a
good thing? :slight_smile:

Um. They *are* the same thing.

"a += i" is syntax magic for "a = a + i". Perhaps you're referring
to something like:

  def app1(a, i); a << i; end
  def app2(a, i); a += i; end

And these are *not* the same, and never should be considered the
same. The problem again is that people are coming at it from the
wrong perspective.

You might say that the typical programmer has grown accustomed to
a confusing model, and Ruby is better off without that model. But,
that is nigh on saying that Ruby is better off without the typical
programmer. And that would be a shame, since Ruby has much to
offer the hordes of Perl and Python programmers looking for
something better.

Except that Ruby's call model isn't that far from the way that Perl
works. Probably not far from Python's model, either.

Ruby does *not* support call-by-reference, in the traditional
sense of the term. Instead, it is strictly call-by-value, and
formal paremeters are copies of references from the calling scope.
If Ruby had real call-by-reference, then it would be trivial to
define a procedure that updates a variable from its parent's
scope, and inc1 and inc2 above would be equivalent.

Again, inc1 and inc2 are equivalent. However, Ruby doesn't have or
need "real" call-by-reference. Too many risks of bad programming
options, IMO.

I think Ruby itself should not be changed. (Though it would be
nice if it had something like Binding.of_caller built-in...)

Tcl is similar to Ruby, regarding both the style of variable
passing and the resulting confusion among its new adopters, but
Tcl documentation has always stressed the details of this issue,
and the Tcl core has the "uplevel" and "upvar" builtins. I'm not a
huge fan of Tcl, but I do think the Tcl folks handled this issue
in the best way possible.

Right. Now that we've got a way of expressing this clearly (Ruby's
calling semantics are pass-reference-by-value), this should no
longer be a source of confusion as documentation is updated.

-austin

···

On Wed, 19 Jan 2005 23:03:59 +0900, Glenn Parker <glenn.parker@comcast.net> wrote:
--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

Glenn Parker wrote:

See my earlier posting about the lambda { } and Variable[:name] ways of doing this.

Sorry, but I can't believe anybody would actually want to use the lambda styles as proposed. They are ugly and obscure.

They are wordy only when you want to increment multiple variables from the outside. That does not hold true for simpler cases:

def inc() yield(1) end

inc { |x| var += x }

Or yet simpler:

def inc() yield end
inc { var += 1 }

I've not yet seen any sample code where the existing ways would not be simple enough. Note that it's possible to write inc(Variable[:x]) when using variable.rb. The implementation is reasonably straight-forward so I don't see why something like this has to be included in core Ruby. Especially not if it seems to be so rarely used in real world code. (Unless said user is using it as a replacement for something that is usually done in a simpler way in Ruby.)

Ruby itself just treats variables as names for Objects. You can't really refer to a variable itself, you can only refer to the Object it is a name for. That's a surprisingly simple and non-confusing model.

Judging by the frequency that this issue is discussed, it's more confusing than you suggest. A typical programmers expects call-by-reference to work one way, and Ruby works differently.

Which might be entirely related to Ruby not being like every other language out there. (And not every other language out there is like every other language out there either.) Personally, I think Ruby's semantics when it comes to variables and argument passing are way less confusing than the ones in Perl and PHP.

If I'm not completely wrong Python, LISP, Smalltalk and JavaScript work exactly in the same way that Ruby does.

Extra confusion results because this difference is masked by using self-updating methods

I've not yet seen a language that tries as hard as Ruby to distinguish between in-place and result-style methods. Other languages usually just do nothing about the issue at all. In that case you have to read the documentation to know what is happening. (Frequently operations are in-place unless the Object is a Value object.)

but it always fails for immediate objects

Of course. How would you change the value of an immutable Object?

and it eventually fails in a surprising way for non-immediate objects. I call it surprising because a typical programmer does not expect the assignment operator to destroy call-by-reference, but that is exactly what happens.

  def inc1(a, i); a += i; end
  def inc2(a, i); a = a + i; end

To the naive Ruby programmer, inc1 and inc2 seem to be equivalent, but Ruby gurus just shake their heads and sigh while they explain, yet again, that there is a difference. Why is this considered a good thing? :slight_smile:

I fear that most people confuse themselves by assuming that Ruby works like other languages they know. That leads to a confusingly over-complicated model. Just forget everything you know and get your knowledge from the Pickaxe. Ruby's model is really quite simple, but people are constantly making up broken metaphors for themselves which is not worth the effort at all...

I think the above code is an example of this. I don't see why the two should be different and unless matz went insane over night they aren't.

You might say that the typical programmer has grown accustomed to a confusing model, and Ruby is better off without that model. But, that is nigh on saying that Ruby is better off without the typical programmer. And that would be a shame, since Ruby has much to offer the hordes of Perl and Python programmers looking for something better.

There's nothing wrong with being used to model's of other languages, but it's a bad idea to mix them up when they don't match.

There's not one true model for everyone, but Ruby's certainly makes sense.

Ruby does *not* support call-by-reference, in the traditional sense of the term. Instead, it is strictly call-by-value, and formal paremeters are copies of references from the calling scope. If Ruby had real call-by-reference, then it would be trivial to define a procedure that updates a variable from its parent's scope, and inc1 and inc2 above would be equivalent.

I'll still want to explain this differently, to keep confusing at a minimum:

Ruby does not pass references to variables, it passes references to Objects.

(Variables are no shoe boxes in Ruby, they are just names for things.)

Tcl is similar to Ruby, regarding both the style of variable passing and the resulting confusion among its new adopters, but Tcl documentation has always stressed the details of this issue, and the Tcl core has the "uplevel" and "upvar" builtins. I'm not a huge fan of Tcl, but I do think the Tcl folks handled this issue in the best way possible.

I'm not experienced at Tcl. What do those built ins do?

trans. wrote:

Right. I'm not suggesting that Ruby change this. I'm just wondering if
might be possible to add an extra feature that would allow for the
alternate when passing arguments through methods.

Please, don't. That would actually make all this wrong thinking models right in certain cases which would make the whole situation vastly more complex. I like Ruby being a simple and consistent language instead of a monster like C++.

Personally, I've alwasy thought of variables as containters, so in that
way of thinking, which I think is common, one would expect to be able
to change what's in the container. I don't think Ruby's approach is
always simple for the enduser and it does lead to some surprises --for
example this very thread.

But this is the very source of all this confusion. Variables are names. I don't know how often I will have to repeat this. :slight_smile:

Binding.of_caller is useful for meta-programming, but that's bad
business for general use.

It's also needed for wrapping eval() and useful for providing convenient interfaces to slightly context-sensitive things. (Breakpoints are an example of that.) I'd like to see it in the language itself, having to go through a Binding for modifying variables or calling methods in another context should give you a hint that you should not use it when you don't need it.

Mohammad Khan wrote:

> But what about scenario 2? [methods changes state of an Object that
> it gets as an argument] Scenario 2 is not acting as scenario 1, is it
> because scenario 2 gets object rather than variable? Or, Scenario 2
> gets clonable object while scenario 1 not?

First, let's agree on using the term "mutable" (or "changeable") instead
of "cloneable". (Immutable objects can not be cloned most of the time,
but the both terms are not strictly the same things.)

agreed on using term 'mutable'.

Scenario 2 changes attributes of an Object. This is something that is
entirely possible. It makes sense for a CarFactory object to be stopped
or running -- it also makes sense that you are able to stop or (re)start
such an object at run time. What can not be done is changing the value
of a variable that appeared in the method invocation because the method
does not know anything about the variable -- it gets the Object. Objects
can have state that can be changed. This can happen via accessors that
are invoked like obj.foo = x or other methods like car_factory.stop.
But while obj.foo looks similar to variable assignment it is something
entirely else.

Why do different things look so similar in Ruby? It's uniform access at
work.

In other languages there usually is the distinction between Object's
fields and methods. Having public fields is usually a bad idea (it
breaks encapsulation) and looks like this:

   obj.field += 5

Having methods that modify state looks like this:

   obj.setField(obj.getField() + 5)

In Ruby both look like this:

   obj.field += 5

Even if obj.field=() or obj.field() do not directly map to an instance
variable at all like in this case:

   def obj.radius()
     @diameter / 2
   end

   def obj.radius=(new_radius)
     @diameter = new_radius * 2
   end

I hope this explains how Ruby works. If there is still anything left
that you don't understand, feel free to ask.

Thanks for your GREAT explanation.

In my two scenarios, we were dealing with two things: variable and object.
If everything is object ... variable is coming from where?
In other words, what is the relation between variable and object.
Are non-mutable objects considered as variables?

Thanks again,
MOhammad

···

On Wed, 2005-01-19 at 12:31, Florian Gross wrote:

> See my earlier posting about the lambda { } and Variable[:name] ways of
> doing this.

Sorry, but I can't believe anybody would actually want to use the lambda
styles as proposed. They are ugly and obscure

Rightly so. I can't see any reason for .succ! to exist, really, and
only very rarely use !versions of methods anyway. The functional style
has kept a lot of bugs out of my programs.

It would be great if we can do
a = Integer.new(1)
b = Integer.new(2)
c = Integer.new(3)

and we can pass object a, b, c rather than variable a, b, c.

Thanks Austin and Florian for explaining variables and object.

···

On Wed, 2005-01-19 at 12:54, Austin Ziegler wrote:

On Thu, 20 Jan 2005 02:17:19 +0900, Mohammad Khan <mkhan@lextranet.com> wrote:
>> a, b, and c are not objects. They're variables.
> Isn't everything *object* in Ruby?
> Now you know, what I am after ?!

Yes, and no.

  a = 1
  b = 2
  c = 3

--
MOhammad

The values 1, 2, and 3 are objects. a, b, and c are not objects.

  def foo(a, b, c)
  end

In #foo, a, b, and c are most definitely NOT objects -- they're
variables that (will) contain references to objects.

In Ruby, variables are names, not memory slots.

  a = b = 1

The real memory slot is more or less identified by Object#id. The
variable is just a convenience label for that object. Change the
object that the label is pointing to, and you just change the
position of the label's name. You're not actually changing the
memory location involved.

What you're after is something you shouldn't do with Ruby. Rethink
your design.

-austin

trans. said:

Personally, I've alwasy thought of variables as containters,

A perfectly good way to think of variables in FORTRAN, Ada, Pascal,
Eiffel, C, C++, C#, Java, FORTH and Algol. In these languages variables
are containers into which you put values (I call this the shoebox model of
variables).

However, it is misleading in Python, Lisp, Scheme and, of course, Ruby.
In these languages, thinking of assignment as binding (associating) a name
to a value is more productive in that you can reason about the language
purely in terms of objects and names associated with objects. No need to
introduce the concept of references. And the difference between immediate
objects and reference objects (almost[1]) melts away.

For more thoughts on this, see:
http://onestepback.org/index.cgi/Tech/Ruby/Shoeboxes.rdoc\. For an example
of "breaking" the rules and re-introducing references in the mix, see:
http://onestepback.org/index.cgi/Tech/Ruby/RubyBindings.rdoc\.

···

--
-- Jim Weirich jim@weirichhouse.org http://onestepback.org
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)

[1] Almost, but not quite. Immediate objects still can't have singleton
methods.

It's easy to accomplish this task with strings:

def do_something(a, b, c)
   a.replace((a.to_i + 1).to_s)
   b.replace((b.to_i + 2).to_s)
   c.replace((c.to_i + 3).to_s)
end

a, b, c = '5', '6', '7'
do_something(a, b, c)

It would be nice to have a replace method for every object, then we could write:

def do_something(a, b, c)
   a.replace(a + 1)
   b.replace(b + 2)
   c.replace(c + 3)
end

a, b, c = 5, 6, 7
do_something(a, b, c)

sorry if this offends, but there is no less blunt way to say it.
if anyone need it. they've gone wrong already.
the solution: design

That's silly. By that line of reasoning, nearly every other language
has got it wrong. Wrong must be pretty good since Ruby is no where near
as popular as those languages that can do this sort of thing.

I think the problem with Ruby is that it _can be done_ if you use
certain _types_ of objects, but not others. That to me goes against the
feather of our friendly duck.

Different things entirely.

Variables are labels, names. They aren't objects. They're ways that
we, the programmers, can refer to objects.

In general, we can't do any operations against variables, because
the name is discarded at the time of execution -- only the object
exists.

-austin

···

On Thu, 20 Jan 2005 02:42:42 +0900, Mohammad Khan <mkhan@lextranet.com> wrote:

In my two scenarios, we were dealing with two things: variable
and object. If everything is object ... variable is coming from
where? In other words, what is the relation between variable and
object. Are non-mutable objects considered as variables?

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

Mohammad Khan wrote:

Mohammad Khan wrote:

> But what about scenario 2? [methods changes state of an Object that
> it gets as an argument] Scenario 2 is not acting as scenario 1, is it
> because scenario 2 gets object rather than variable? Or, Scenario 2
> gets clonable object while scenario 1 not?

First, let's agree on using the term "mutable" (or "changeable") instead
of "cloneable". (Immutable objects can not be cloned most of the time,
but the both terms are not strictly the same things.)

agreed on using term 'mutable'.

Scenario 2 changes attributes of an Object. This is something that is
entirely possible. It makes sense for a CarFactory object to be stopped
or running -- it also makes sense that you are able to stop or (re)start
such an object at run time. What can not be done is changing the value
of a variable that appeared in the method invocation because the method
does not know anything about the variable -- it gets the Object. Objects
can have state that can be changed. This can happen via accessors that
are invoked like obj.foo = x or other methods like car_factory.stop.
But while obj.foo looks similar to variable assignment it is something
entirely else.

Why do different things look so similar in Ruby? It's uniform access at
work.

In other languages there usually is the distinction between Object's
fields and methods. Having public fields is usually a bad idea (it
breaks encapsulation) and looks like this:

obj.field += 5

Having methods that modify state looks like this:

obj.setField(obj.getField() + 5)

In Ruby both look like this:

obj.field += 5

Even if obj.field=() or obj.field() do not directly map to an instance
variable at all like in this case:

def obj.radius()
@diameter / 2
end

def obj.radius=(new_radius)
@diameter = new_radius * 2
end

I hope this explains how Ruby works. If there is still anything left
that you don't understand, feel free to ask.

Thanks for your GREAT explanation.

In my two scenarios, we were dealing with two things: variable and
object. If everything is object ... variable is coming from where?
In other words, what is the relation between variable and object.
Are non-mutable objects considered as variables?

You have to tell ruby what object you want to pass
in a method or to what object a message should be sent.
A variable is just a name for an object.

def do_something(a)
  # inside this method you can access
  # the object passed to the method with the name a
  ...
end

x = Object.new
# You can do something with the new created
# object by specifying its name, the variable x

# Tell ruby to pass the object named by x
# to the method do_something
do_something(x)
# Inside do_something the method can access
# our object with the name a (look above)

···

On Wed, 2005-01-19 at 12:31, Florian Gross wrote:

Mohammad Khan wrote:

It would be great if we can do
a = Integer.new(1)
b = Integer.new(2)
c = Integer.new(3)

Which would be Objects whose values can be changed?

I don't know, I think I would find it confusing if I'd do five = Integer.new(5); some_method(five) and if after that five * five would not be 25.

David A. Black wrote:

def inc1(a, i); a += i; end
def inc2(a, i); a = a + i; end

In any case, I believe the two things in your example are actually
equivalent. My understanding is that Ruby always expands:
   x += y
to
   x = x + y

Ouch! That's what I get for posting code without trying it out first. Even something that trivial tripped me up, and I should know better. :frowning:

Austin Ziegler wrote:

"a += i" is syntax magic for "a = a + i". Perhaps you're referring
to something like:

  def app1(a, i); a << i; end
  def app2(a, i); a += i; end

Right, that is closer to what I was trying to illustrate. As to whether those two should be considered equivalent, I assert each person's answer will depend on their expectations and their prior experience. :slight_smile:

Austin Ziegler wrote:

Except that Ruby's call model isn't that far from the way that Perl
works. Probably not far from Python's model, either.

Perl generally uses call-by-value, but it also supports call-by-reference using the backslash operator:

   sub inc {
     $arg = shift @_;
     $$arg += 1;
   }
   $x = 1;
   inc(\$x);
   print $x;

This prints "2". Here, "\$x" is a reference to $x, and "inc" assigns it to $arg. $$arg dereferences the reference, allowing inc to modify $x directly.

Like Ruby, Python doesn't seem to have any support for call-by-reference, and Python coders have been through the exact same discussion that we're having here (almost word-for-word): http://mail.python.org/pipermail/python-list/2001-June/048603.html

Florian Gross wrote:

the Tcl core has the "uplevel" and "upvar" builtins.

I'm not experienced at Tcl. What do those built ins do?

Tcl's "upvar" is a generalized call-by-reference method. It allows a function to bind a local variable to variable from the calling scope.

   proc inc name {
     upvar $name a
     set a [expr $a + 1]
   }
   set x 1
   inc x
   puts $x

This also prints "2". In this case, "a" becomes an alias for "x" after the call to upvar. Tcl's "uplevel" is very similar in concept to Binding.of_caller, allowing execution of code in the caller's scope. Tcl coders can use uplevel to create new flow-of-control structures.

I've seen one or two posts here that flat out denigrate call-by-reference, or suggest that it is a workaround necessitated by weak language design. This is a narrow view, IMHO. If we can define methods that modify an object in place, then we are already halfway to using call-by-reference semantics.

Oh well, this was probably more educational for me than for anybody else, so thanks to everybody for your patience.

···

On Wed, 19 Jan 2005, Glenn Parker wrote:

--
Glenn Parker | glenn.parker-AT-comcast.net | <http://www.tetrafoil.com/&gt;

Hi --

···

On Thu, 20 Jan 2005, Michel Martens wrote:

It's easy to accomplish this task with strings:

def do_something(a, b, c)
  a.replace((a.to_i + 1).to_s)
  b.replace((b.to_i + 2).to_s)
  c.replace((c.to_i + 3).to_s)
end

a, b, c = '5', '6', '7'
do_something(a, b, c)

It would be nice to have a replace method for every object, then we could write:

def do_something(a, b, c)
  a.replace(a + 1)
  b.replace(b + 2)
  c.replace(c + 3)
end

a, b, c = 5, 6, 7
do_something(a, b, c)

What would you replace 5 with? :slight_smile:

(Remember, you're sending the 'replace' method to an *object*, not an
identifier.)

David

--
David A. Black
dblack@wobblini.net

Michel Martens wrote:

It's easy to accomplish this task with strings:

def do_something(a, b, c)
   a.replace((a.to_i + 1).to_s)
   b.replace((b.to_i + 2).to_s)
   c.replace((c.to_i + 3).to_s)
end

a, b, c = '5', '6', '7'
do_something(a, b, c)

It would be nice to have a replace method for every object, then we could
write:

def do_something(a, b, c)
   a.replace(a + 1)
   b.replace(b + 2)
   c.replace(c + 3)
end

a, b, c = 5, 6, 7
do_something(a, b, c)

But replace doesn't replace the object the variable
points to, it just replaces instance variables of the
string object:

irb(main):001:0> s = "abc"
=> "abc"
irb(main):002:0> s.object_id
=> 538462462
irb(main):003:0> s.replace "xyz"
=> "xyz"
irb(main):004:0> s
=> "xyz"
irb(main):005:0> s.object_id
=> 538462462

You can write your replace method if you like:

class A
  attr_reader :ivar
  def replace(a_obj)
    @ivar = a_obj.ivar
    # or generally copy all
    # instance vars
  end
end

def do_something(obj)
  ...
  obj.replace(other)
end

a = A.new
do_something(a)
p a

···

--
Stefan

sure. people who want quick unmaintainable hacks shouldn't use ruby i guess.

Alex

···

On Jan 19, 2005, at 5:01 PM, trans. wrote:

sorry if this offends, but there is no less blunt way to say it.
if anyone need it. they've gone wrong already.
the solution: design

That's silly. By that line of reasoning, nearly every other language
has got it wrong. Wrong must be pretty good since Ruby is no where near
as popular as those languages that can do this sort of thing.