Call-by-reference problem again

Hi there,

I encountered the call-by-reference problem, which was discussed before
in this group. Please have a look at the following code:

def test!(str)
str=str.upcase
end
str=“hello"
print str,”\n"
test!(str)
print str,"\n"

The str is not turned into upcase. This seems clear since that “Ruby
only pass by value”. According to a post in this group, I tried change
the parameter into an array, and it worked.

The problem here is, we have seen some Ruby methods, like String.chomp!
and many that end with a !, they can modify parameters in place, how is
it done?? Is it possible to do this in programming, or is it only
available in standard libraries, which may be implemented outside of
ruby (eg. in C)?

tks
Shannon

Hi,

In general, for the Ruby built-in classes such as String, the methods are
indeed implemented in C. For your own classes, probably it suffices to
say that you cannot modify ‘self’ (such as ‘self = something’) in Ruby,
but it is possible do that through the Ruby C API’s.

Ruby restricts you from doing certain operations, but if you also use the
Ruby C API’s, as the pickaxe book says, “the possibilities are
endless” (not mentioning if you also start to modify the Ruby source code
itself for your own personal library…)

Regards,

Bill

···

Shannon Fang xrfang@hotmail.com wrote:

The problem here is, we have seen some Ruby methods, like String.chomp!
and many that end with a !, they can modify parameters in place, how is
it done?? Is it possible to do this in programming, or is it only
available in standard libraries, which may be implemented outside of
ruby (eg. in C)?

Hi –

Hi there,

I encountered the call-by-reference problem, which was discussed before
in this group. Please have a look at the following code:

def test!(str)
str=str.upcase
end
str=“hello”
print str,“\n”
test!(str)
print str,“\n”

The str is not turned into upcase. This seems clear since that “Ruby
only pass by value”. According to a post in this group, I tried change
the parameter into an array, and it worked.

What’s happening here is that you’ve got a local variable, str, and
you’re assigning a new object reference to it.

When you do:

str = str.upcase

you lose the reference that str started with. You’re just reusing the
name “str”.

Strings are indeed changeable in place, so you could do:

def test!(str)
str.replace(str.upcase) # or str.upcase!
end

and that will do what you were expecting.

The problem here is, we have seen some Ruby methods, like String.chomp!
and many that end with a !, they can modify parameters in place, how is
it done?? Is it possible to do this in programming, or is it only
available in standard libraries, which may be implemented outside of
ruby (eg. in C)?

Actually ! methods generally modify the receiver (self) in place, or
change its state in some way. You can write your own; it’s just a
stylistic convention to indicate that this kind of change is going on.
For example:

class Word < String
def translate
case self
when “one” then “un”
when “two” then “deux”
when “three” then “trois”
else self
end
end
def translate!
replace(translate)
end
end

w = Word.new(“two”)
p w.translate # “deux”
p w # “two”
p w.translate! # “deux”
p w # “deux”

David

···

On Thu, 28 Nov 2002, Shannon Fang wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Hi,

Hi there,

I encountered the call-by-reference problem, which was discussed before
in this group. Please have a look at the following code:

I’m confident the gurus can give more precision in their replies,
but here’s my thought(s)…

def test!(str)
str=str.upcase
end

def test!(str)
str.upcase!
end

str=“hello”
print str,“\n”
test!(str)
print str,“\n”

The str is not turned into upcase. This seems clear since that “Ruby
only pass by value”. According to a post in this group, I tried change
the parameter into an array, and it worked.

The problem here is, we have seen some Ruby methods, like String.chomp!
and many that end with a !, they can modify parameters in place, how is
it done?? Is it possible to do this in programming, or is it only
available in standard libraries, which may be implemented outside of
ruby (eg. in C)?

Some of the Ruby built-ins, such as String, do provide ways to
swap-out their contents in-place. For instance, String#=

def test!(str); str[0…-1] = “some other str”; end
nil
x = “xyzzy”
“xyzzy”
x.id
22441516
test!(x)
“some other str”
x
“some other str”
x.id
22441516

Here you can tell the contents of ‘x’ (the String object instance
referred to by ‘x’) were changed to a completely different string-text,
yet ‘x’ still refers to the original, same instance it has all
along…

However, as some recent discussions have pointed out, not all Ruby
objects are mutable… So there is no way I know of to implement
a Ruby method like test!() above for Fixnum, or Bignum, …

But certainly in your own Ruby classes, it’s up to you how many
test!-like methods you want to create. (Since you have access to
the internals of your own object, in terms of its instance
variables… [Modulo inheritance and the discussion of “private
instance variables” ])

Anyway I believe the short answer is, essentialy: You can implement
self-changing* methods in your own Ruby classes, and some of the
built-ins provide ways to change their contents out as well…

Hope this helps,

Bill

(*) Not talking about assignment to “self”, which isn’t allowed…

···

From: “Shannon Fang” xrfang@hotmail.com

Hello Shannon,

Wednesday, November 27, 2002, 11:52:59 PM, you wrote:

I encountered the call-by-reference problem, which was discussed
before in this group. Please have a look at the following code:

def test!(str)
str=str.upcase
end
str=“hello”
print str,“\n”
test!(str)
print str,“\n”

def test!(str)
str.upcase!
end

The problem here is, we have seen some Ruby methods, like String.chomp!
and many that end with a !, they can modify parameters in place, how is
it done?? Is it possible to do this in programming, or is it only
available in standard libraries, which may be implemented outside of
ruby (eg. in C)?

ruby is not created with ability to modify parameters in mind. so you
must not rely on this programming paradigm. use arrays or multiple
return values or something other

···


Best regards,
Bulat mailto:bulatz@integ.ru

William Djaja Tjokroaminata billtj@y.glue.umd.edu writes:

The problem here is, we have seen some Ruby methods, like String.chomp!
and many that end with a !, they can modify parameters in place, how is
it done?? Is it possible to do this in programming, or is it only
available in standard libraries, which may be implemented outside of
ruby (eg. in C)?

Hi,

In general, for the Ruby built-in classes such as String, the methods are
indeed implemented in C. For your own classes, probably it suffices to
say that you cannot modify ‘self’ (such as ‘self = something’) in Ruby,
but it is possible do that through the Ruby C API’s.

That’s not really the point. A ! method modifies the state of an
object, not its value of ‘self’. For example

class Counter
attr_reader :count

 def initialize(value=0)
   @count = value
 end

 def succ
   Counter.new(@count.succ)
 end

 def succ!
    @count += 1
    self
 end
end


a = Counter.new
p a.count     #=> 0
b = a
c = a.succ
p b.count     #=> 0
p c.count     #=> 1
c = a.succ!
p b.count     #=> 1
p c.count     #=> 1

It’s the same for Strings. Mutators change the state of the object:
the object reference stays the same.

Dave

···

Shannon Fang xrfang@hotmail.com wrote:

Hello,

···

----- Original Message -----
[snip]

ruby is not created with ability to modify parameters in mind. so you
must not rely on this programming paradigm. use arrays or multiple
return values or something other

Huh?

Do you mean that Ruby wasn’t created with the ability to modify parameter
variables, or the objects passed in as parameters? You can certainly
modify the objects (to the extent that their methods allow).

In the original email (and I hope you are viewing this in a monospaced
font), the problem was simply (assuming ‘str’ referenced the object
“hello”):

          First, "hello".upcase returns
              a *new* string object
                        >
                        >

±> str = str.upcase <–+

±- Then the local variable
‘str’ is set to this new
string, thus losing all
reference to the original
string.

Parameters are local variables. Perhaps the confusion is that blocks
don’t work this way (I think).

Chris

In my class, I read some string from a text file, and store it in a
local variable, then I defined a private method passing it the local
variable, do some converstion, before it return, I tried to clear the
string to “”. It seems I can’t do it.

A solution I am now thinking is that I do not use a local variable,
instead, use a instant variable… What do you think?

Shannon

···

On Thu, 28 Nov 2002 06:45:26 +0900 Dave Thomas Dave@PragmaticProgrammer.com wrote:

William Djaja Tjokroaminata billtj@y.glue.umd.edu writes:

Shannon Fang xrfang@hotmail.com wrote:

The problem here is, we have seen some Ruby methods, like String.chomp!
and many that end with a !, they can modify parameters in place, how is
it done?? Is it possible to do this in programming, or is it only
available in standard libraries, which may be implemented outside of
ruby (eg. in C)?

Hi,

In general, for the Ruby built-in classes such as String, the methods are
indeed implemented in C. For your own classes, probably it suffices to
say that you cannot modify ‘self’ (such as ‘self = something’) in Ruby,
but it is possible do that through the Ruby C API’s.

That’s not really the point. A ! method modifies the state of an
object, not its value of ‘self’. For example

class Counter
attr_reader :count

 def initialize(value=0)
   @count = value
 end

 def succ
   Counter.new(@count.succ)
 end

 def succ!
    @count += 1
    self
 end
end


a = Counter.new
p a.count     #=> 0
b = a
c = a.succ
p b.count     #=> 0
p c.count     #=> 1
c = a.succ!
p b.count     #=> 1
p c.count     #=> 1

It’s the same for Strings. Mutators change the state of the object:
the object reference stays the same.

Dave

Another problem about reference is that,
if a is an object, let b=a, then b is a copy of the object or a pointer
to a? I encountered the following problem

a=b=c=Array.new
d=e=f=“”

In my program, if I modify a, b and c will be affected, in another word,
a, b, c point to the same Array. while I modify d, e and f are not
affected, which means, strings are assigned by value… what will happen
if I write d=e=f=String.new?

Since everything in Ruby is object, I don’t understand why String and
Array are different…

Shannon

···

On Thu, 28 Nov 2002 06:45:26 +0900 Dave Thomas Dave@PragmaticProgrammer.com wrote:

William Djaja Tjokroaminata billtj@y.glue.umd.edu writes:

Shannon Fang xrfang@hotmail.com wrote:

The problem here is, we have seen some Ruby methods, like String.chomp!
and many that end with a !, they can modify parameters in place, how is
it done?? Is it possible to do this in programming, or is it only
available in standard libraries, which may be implemented outside of
ruby (eg. in C)?

Hi,

In general, for the Ruby built-in classes such as String, the methods are
indeed implemented in C. For your own classes, probably it suffices to
say that you cannot modify ‘self’ (such as ‘self = something’) in Ruby,
but it is possible do that through the Ruby C API’s.

That’s not really the point. A ! method modifies the state of an
object, not its value of ‘self’. For example

class Counter
attr_reader :count

 def initialize(value=0)
   @count = value
 end

 def succ
   Counter.new(@count.succ)
 end

 def succ!
    @count += 1
    self
 end
end


a = Counter.new
p a.count     #=> 0
b = a
c = a.succ
p b.count     #=> 0
p c.count     #=> 1
c = a.succ!
p b.count     #=> 1
p c.count     #=> 1

It’s the same for Strings. Mutators change the state of the object:
the object reference stays the same.

Dave

Hello Chris,

Thursday, November 28, 2002, 6:12:02 PM, you wrote:

···

----- Original Message -----
[snip]

ruby is not created with ability to modify parameters in mind. so you
must not rely on this programming paradigm. use arrays or multiple
return values or something other

Huh?

Do you mean that Ruby wasn’t created with the ability to modify parameter
variables,

ya, ya, of course :slight_smile: i’m not so dumb :wink:


Best regards,
Bulat mailto:bulatz@integ.ru

Hi –

···

On Thu, 28 Nov 2002, Shannon Fang wrote:

In my class, I read some string from a text file, and store it in a
local variable, then I defined a private method passing it the local
variable, do some converstion, before it return, I tried to clear the
string to “”. It seems I can’t do it.

You can clear a string like this:

str.replace(“”)

[Is there a String#clear in 1.7 or later?]

David


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Hi –

Another problem about reference is that,
if a is an object, let b=a, then b is a copy of the object or a pointer
to a? I encountered the following problem

a=b=c=Array.new
d=e=f=“”

In my program, if I modify a, b and c will be affected, in another word,
a, b, c point to the same Array. while I modify d, e and f are not
affected, which means, strings are assigned by value… what will happen
if I write d=e=f=String.new?

Since everything in Ruby is object, I don’t understand why String and
Array are different…

It depends what you mean by “modify d”. I have a hunch you might be
doing something like:

d = e = f = “some string”
d = “some other string”

In that case, you’re just reusing the name ‘d’ to refer to a new
object. e and f don’t care about that.

However, if you modifying the underlying object, then all references
to it will reflect those changes:

d = e = f = “some string”
d << " with three references" # append to string, in place

p e # “some string with three references”

David

···

On Thu, 28 Nov 2002, Shannon Fang wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Hi Dave,

I assumed that changing the state of an object using instance variables is
obvious to him (if not, then what else?) Usually the problem that people
having difficulty with is the “apparent impossibility” of “changing”
‘self’.

Regards,

Bill

···

On Thu, 28 Nov 2002 06:45:26 +0900 > Dave Thomas Dave@PragmaticProgrammer.com wrote:

That’s not really the point. A ! method modifies the state of an
object, not its value of ‘self’. For example

Hi Shannon,

I don’t think your statement above is right. In Ruby, if you have

a = b = c = … = anything # Array.new, or “”, or String.new, or else

then if you call a “!” method on any of the above variables, then all the
variables are “affected” because in essence, there is only one single
object, which is referred to by so many variables.

So using your own terminology/concept, in b=a, then b is a copy of the
“pointer” to a, and not a copy of the object pointed to by a. Please see
also http://www.glue.umd.edu/~billtj/ruby.html#objects.

Regards,

Bill

···

Shannon Fang xrfang@hotmail.com wrote:

Another problem about reference is that,
if a is an object, let b=a, then b is a copy of the object or a pointer
to a? I encountered the following problem

a=b=c=Array.new
d=e=f=“”

In my program, if I modify a, b and c will be affected, in another word,
a, b, c point to the same Array. while I modify d, e and f are not
affected, which means, strings are assigned by value… what will happen
if I write d=e=f=String.new?

Since everything in Ruby is object, I don’t understand why String and
Array are different…

Shannon

Hello Shannon,

Thursday, November 28, 2002, 12:54:37 AM, you wrote:

a=b=c=Array.new
d=e=f=“”

In my program, if I modify a, b and c will be affected, in another word,
a, b, c point to the same Array. while I modify d, e and f are not
affected, which means, strings are assigned by value… what will happen
if I write d=e=f=String.new?

it’s because you use self-modifying methods in one case and create new
objects in another. try this code :slight_smile:

a=b=c=Array.new
d=e=f=“”

a += [1]
d << “a”

···


Best regards,
Bulat mailto:bulatz@integ.ru

I’m attempting to map output of a ‘system’ call
directly in to an FXText window.

f = IO.popen(‘cmd /C foo.exe’)
myTextBox.appendText(f.read)

is one way, but it waits until the app is done before
updating the window.

I’ve been looking for ways to change $stdout or
something so that whatever the seperate app generates,
it actually just goes straight to the window.

textBoxStream = IO.new($stdout.fileno,“w”)
def textBoxStream.putc(char)
myTextBox.appendText(char)
end

Something like that?

Gah.

Hi Bill,
In my test the Arrays are all pointing to the same object, but the
strings are not. I now understand that david has explained what happed
in my prog.

tks.
shannon

···

On Thu, 28 Nov 2002 08:15:18 +0900 William Djaja Tjokroaminata billtj@y.glue.umd.edu wrote:

Shannon Fang xrfang@hotmail.com wrote:

Another problem about reference is that,
if a is an object, let b=a, then b is a copy of the object or a pointer
to a? I encountered the following problem

a=b=c=Array.new
d=e=f=“”

In my program, if I modify a, b and c will be affected, in another word,
a, b, c point to the same Array. while I modify d, e and f are not
affected, which means, strings are assigned by value… what will happen
if I write d=e=f=String.new?

Since everything in Ruby is object, I don’t understand why String and
Array are different…

Shannon

Hi Shannon,

I don’t think your statement above is right. In Ruby, if you have

a = b = c = … = anything # Array.new, or “”, or String.new, or else

then if you call a “!” method on any of the above variables, then all the
variables are “affected” because in essence, there is only one single
object, which is referred to by so many variables.

So using your own terminology/concept, in b=a, then b is a copy of the
“pointer” to a, and not a copy of the object pointed to by a. Please see
also http://www.glue.umd.edu/~billtj/ruby.html#objects.

Regards,

Bill

Jason Persampieri wrote:

I’m attempting to map output of a ‘system’ call
directly in to an FXText window.

You might want to take a look at the inputs.rb example program that
comes with FXRuby, although I’m not sure how well it’s going to work on
Windows. There is a (non-FXRuby related) problem with doing non-blocking
file I/O on Windows and I’m not sure that it has been resolved yet.

P.S.

Can you (privately) send me some more information about how to reproduce
the problem you described in your SF bug report about long file names?
Please provide specifics (and if possible a sample program that
demonstrates the problem).

Hi Shannon,

Can you give me the code where arrays are behaving differently from
strings?

Bill

···

Shannon Fang xrfang@hotmail.com wrote:

Hi Bill,
In my test the Arrays are all pointing to the same object, but the
strings are not. I now understand that david has explained what happed
in my prog.

Jason Persampieri wrote:

I’m attempting to map output of a ‘system’ call
directly in to an FXText window.

You might want to take a look at the inputs.rb
example program that
comes with FXRuby, although I’m not sure how well
it’s going to work on
Windows. There is a (non-FXRuby related) problem
with doing non-blocking
file I/O on Windows and I’m not sure that it has
been resolved yet.

P.S.

Can you (privately) send me some more information
about how to reproduce
the problem you described in your SF bug report
about long file names?
Please provide specifics (and if possible a sample
program that
demonstrates the problem).

···

— Lyle Johnson lyle@users.sourceforge.net wrote: