Hi --

On Thu, 28 Nov 2002, Shannon Fang wrote:

> 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

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