Passing script input as method args always global?

On Wed, Nov 13, 2013 at 1:23 PM, gvim [email protected] wrote:

On 13/11/2013 12:13, Xavier N. wrote:

value. Ruby passes references to objects by value.
return y
end

puts f(x) #=> 3
puts x #=> 2

In your example a and b are mutated but in mine x remains unchanged.

That example illustrates what you could do if you had pass by
reference
semantics. And Ruby does not have those semantics, it has pass by value
semantics, therefore it works as you are seeing.

Gerald Vim wrote in post #1127142:

On 13/11/2013 11:32, Carlo E. Prelz wrote:

x = x + 1

So a parameter is passed by reference but as soon as you modify it
you’ve cloned the object?

No, not at all.

``x = x + 1’’ breaks down like this:

  1. construct an object which is an Integer whose value is 1
  2. find the object referred to by the variable named “x”; in this case,
    an Integer
  3. invoke the method called “+” on that object, passing the newly-minted
    Integer as the first/only parameter*
  4. update the variable named “x” to refer to the result of that method
    invocation (i.e. this is the “=” part)

*Note: the “+” method on an Integer is non-destructive, internally it
creates a new Integer object whose value is the sum of the receiver and
the parameter, and returns that. Integer objects are immutable in ruby.

There are all sorts of other specifics going on (singleton Fixnums for
starters) but this simplification isn’t inaccurate. Assignment is an
operation on the variable (a reference), and method invocations
(including “+”) are operations on the object referred to by the
variable.


Here is a counter-example, assuming y = “abc”, because I like writing
more than necessary:

y = ( y << “d” )

  1. construct an object which is a String whose value is “d”
  2. find the object referred to by the variable named “y”; in this case,
    our a String
  3. invoke the method called “<<” on that object, passing the
    newly-minted String as the first/only parameter
  4. update the variable named “y” to refer to the result of that method
    invocation

In this case the “<<” method on a String is destructive; it changes
the value of the Object, by appending the parameter to it. Fortunately
for
us, it also returns the (now updated) receiver. We could have left the
code as:

y << “d”

… which would have saved us a variable assignment, but both snippets
result in an identical state.

Subject: Re: Passing script input as method args always global?
Date: mer 13 nov 13 12:23:22 +0000

Quoting gvim ([email protected]):

In your example a and b are mutated but in mine x remains unchanged.

Because in your method:

def f(y)
y = y + 1
return y
end

you receive an object, but you return another one. The fact that it is
still called ‘y’ (within your local method) does not insure that it is
the same thing.

Thus, the original object is indeed unchanged.

This is because the implementators of the sum of the Numeric class
decided that it was appropriate to return a new object when performing
a sum.

If you go back to my previous example, and substitute the plus method
so that instead of

def +(new_v)
@v+=new_v
self
end

it reads

def +(new_v)
Tally::new(@v+new_v)
end

(note that I changed the name of the local variable so that things may
be easier to understand), then you will still have

puts f(var) #=> 3
puts var #=> 2

Carlo

Gerald Vim wrote in post #1127156:

On 13/11/2013 12:33, Matthew K. wrote:

  1. update the variable named “x” to refer to the result of that method
    variable.
    our a String

    y << “d”

… which would have saved us a variable assignment, but both snippets
result in an identical state.

I’m beginning to see Ruby’s “everything is an object” as a serious
barrier to comprehension, epsecially when this object-orientation is
dressed up in procedural syntax. Perl seems a lot more natural by
comparison.

gvim

If you like, you can rewrite all of the above as:

x = x.+(1);
y = y.<<(“d”);

Everything else is syntactic sugar.

Also, for the record, there’s this: x += 1
Which expands out to: x = x.+(1)

On 13/11/2013 12:33, Matthew K. wrote:

  1. update the variable named “x” to refer to the result of that method
    variable.
    our a String

    y << “d”

… which would have saved us a variable assignment, but both snippets
result in an identical state.

I’m beginning to see Ruby’s “everything is an object” as a serious
barrier to comprehension, epsecially when this object-orientation is
dressed up in procedural syntax. Perl seems a lot more natural by
comparison.

gvim

On 13/11/2013 12:42, Matthew K. wrote:

If you like, you can rewrite all of the above as:

x = x.+(1);
y = y.<<(“d”);

Everything else is syntactic sugar.

Also, for the record, there’s this: x += 1
Which expands out to: x = x.+(1)

Ruby’s beauty is looking increasingly skin-deep to me as I learn more.

gvim

On Wed, Nov 13, 2013 at 1:39 PM, gvim [email protected] wrote:

I’m beginning to see Ruby’s “everything is an object” as a serious
barrier

to comprehension, epsecially when this object-orientation is dressed up in
procedural syntax. Perl seems a lot more natural by comparison.

Ruby has a simpler model than Perl in this regard. It is easier in that
sense, but coming from Perl you need to adjust.

In Perl you have values (scalars, arrays, hashes, …), and references
to
values (which are in turn scalars). In Ruby you only have references.

That’s the whole story.

In Ruby

s = "foo"
t = s

s << 'bar'
puts t

prints “foobar”. Everything are references, s holds a reference to a
string, t hods the same reference, therefore in-place mutations are seen
in
both of them.

Subject: Re: Passing script input as method args always global?
Date: mer 13 nov 13 12:39:17 +0000

Quoting gvim ([email protected]):

I’m beginning to see Ruby’s “everything is an object” as a serious
barrier to comprehension

barriers to comprehension are made to be overcome. A haiku may be this
one:

class Fixnum
def +(v)
self-v
end
end

val=3
puts val # 3
val=val+1
puts val # what??

Carlo

On 13/11/2013 12:47, Xavier N. wrote:

string, t hods the same reference, therefore in-place mutations are seen
in both of them.

I get that but it sets up an expectation that this:

x =2

def f(y)
y = y + 1
puts y
end

f(x)

… will mutate x but I now understand, from what others have explained,
that it doesn’t. It’s just counter-intuitive, that’s all. This and the
various rules about symbols as named arguments have led me to the
conclusion that Ruby is an unnecessarily complicated language. Perl is
much simpler.

gvim

Subject: Re: Passing script input as method args always global?
Date: mer 13 nov 13 12:52:47 +0000

Quoting gvim ([email protected]):

Ruby’s beauty is looking increasingly skin-deep to me as I learn
more.

What is happening is that you resist change. What you lose seems to
you of greater value than what you gain.

Which might just as well be in your case. It is up to you to
decide whether to dedicate precious brain-space with Ruby.

Ruby’s #1 beauty is for me that it allows you to become an intimate
friend of the OO paradigm without compromises, and with an almost
perfect clarity.

Carlo

On 13/11/2013 12:53, Carlo E. Prelz wrote:

val=3
puts val # 3
val=val+1
puts val # what??

Carlo

I’m sure there are many more contortions like this that Ruby facilitates
but my months spent learning the language have led me to the conclusion
that one can easily get lost in what’s going on in the language under
the surface. It’s surface simplicity and elegance falls apart quite
quickly in my experience.

gvim

On Wed, Nov 13, 2013 at 1:57 PM, gvim [email protected] wrote:

… will mutate x but I now understand, from what others have
explained,

that it doesn’t. It’s just counter-intuitive, that’s all. This and the
various rules about symbols as named arguments have led me to the
conclusion that Ruby is an unnecessarily complicated language. Perl is much
simpler.

The conclusion you need to reach is that you do not understand pass by
value. You need to understand pass by value, is what the vast majority
of
programming languages implement. Perl is the outlier here (not implying
it
is worse, I love Perl, just to put things in perspective).

On 13/11/2013 13:00, Carlo E. Prelz wrote:

Ruby’s #1 beauty is for me that it allows you to become an intimate
friend of the OO paradigm without compromises, and with an almost
perfect clarity.

Carlo

I understand where you’re coming from but for me arithmetic operators
implemented as objects is just plain back-to-front and goes half way to
explaining why my x = x + 1 didn’t behave as expected. Even worse when
those operators can be overridden.

gvim

On 13/11/2013 13:02, Xavier N. wrote:

The conclusion you need to reach is that you do not understand pass by
value. You need to understand pass by value, is what the vast majority
of programming languages implement. Perl is the outlier here (not
implying it is worse, I love Perl, just to put things in perspective).

PHP, I believe, adopted pass-by-reference a few major version back.
Avdi, and others, earlier stated “Args are always passed by reference”
so which is it?

gvim

Subject: Re: Passing script input as method args always global?
Date: mer 13 nov 13 01:05:47 +0000

Quoting gvim ([email protected]):

I understand where you’re coming from but for me arithmetic
operators implemented as objects is just plain back-to-front and
goes half way to explaining why my x = x + 1 didn’t behave as
expected. Even worse when those operators can be overridden.

I am not sure you know where I come from :wink:

Anyway, if you want to gain the advantage that OO gives, you must
learn to consider everything that happens to your things as methods
applied to objects. Once you do that, things will start to make more
sense, I hope.

In Ruby, arithmetic operators are implemented as methods because there
is no other way.

PS in a previous mail I wrote

A haiku may be this one:

I apologize to the many Japanese readers of this list: I meant

A koan may be this one:

Carlo

Gerald Vim wrote in post #1127166:

I’m sure there are many more contortions like this that Ruby facilitates
but my months spent learning the language have led me to the conclusion
that one can easily get lost in what’s going on in the language under
the surface. It’s surface simplicity and elegance falls apart quite
quickly in my experience.

Well, Perl does the same unless explicitly told.

sub f {
    my $y = shift;
    $y = $y + 1;
    return $y;
}

my $x = 2;
print f($x), "\n";   # => 3
print $x, "\n";      # => 2

Java, in contrast, does not know about pass by value and always does
pass by reference.

The most expressive would be C++ here:

float f(float x);
float f_with_sideeffect(float &x);

(And C++ allows to overload operators, too! Have fun with that…)

In general, you’d like to avoid side effects whenever possible.

On 13/11/2013 13:21, Eric MSP Veith wrote:

 my $x = 2;
 print f($x), "\n";   # => 3
 print $x, "\n";      # => 2

The difference is that Perl explicitly shifts the parameter into a new
lexical variable. This is not what’s happening in my Ruby example and
that’s why I find it confusing. Why have a named parameter which is
passed by reference if as soon as you mutate it the reference is lost,
a-la Ruby? This is not what Perl does at all.

gvim

On 13/11/2013 13:21, Eric MSP Veith wrote:

 my $x = 2;
 print f($x), "\n";   # => 3
 print $x, "\n";      # => 2

x = 2
def f(y)
y = y + 1
return y
end

puts f(x) #=> 3
puts x #=> 2

The Perl equivalent is:

my $x =2;
sub f {
$[0] = $[0] + 1;
return $_[0];
}

say f($x); # 3
say $x; # 3

Perl retains the passed reference unless modified. Not so in Ruby where
y becomes a new copy as soon as it is mutated.

gvim

When we talk about “pass by reference”, “reference” means a reference to
the container, to the variable. You have to visualize two symbol tables
that have aliased keys. The value they hold is not relevant to this
terminology. Going through one or the other, you reach the same memory
slot.

On Wed, Nov 13, 2013 at 2:21 PM, Eric MSP Veith
[email protected]wrote:

Gerald Vim wrote in post #1127166:

    my $y = shift;
    $y = $y + 1;
   return $y;
}

my $x = 2;
print f($x), "\n";   # => 3
print $x, "\n";      # => 2

Java, in contrast, does not know about pass by value and always does
pass by reference.

Not true. Java is pass by value, the JLS is clear about this:

When the method or constructor is invoked (§15.12),
the values of the actual argument expressions initialize
newly created parameter variables, each of the declared
Type, before execution of the body of the method or
constructor.

There are many informal resources out there about this debate, see for
example

http://www.javaranch.com/campfire/StoryPassBy.jsp

or

http://architects.dzone.com/articles/java-pass-value-and-not-pass-0

In Ruby, as in Java, the fact that you are dealing with references
belongs
to the conceptual model of the language. It is not the case that you are
supposed to be dealing with objects directly and references are
implementation. The language tells you that you are dealing with
references. (The fact that MRI uses pointers is implementation.)

So in Ruby, as in Java, the arguments hold references, and call
semantics
are pass by value. You pass references to objects by value.