On 21 Aug 2007, at 15:12, Dan wrote:

> Just a small quick question:
>
> String * Fixnum works:
>
> "test " * 4
>    => test test test test
>
>
> while Fixnum * String doesn't:
>
> 4 * "test "
>      TypeError: String can't be coerced into
> Fixnum
>           from (irb):19:in
> `*'
>           from (irb):19
>
> I understand that ruby being strongly typed means you can only do  
> "sensible"
> things with the types you are working with. However, aren't the  
> examples
> above pretty much equivalent? or is it a precedence thing? Trying  
> to answer
> my own question is it because the "*" operator for a Fixnum only  
> accepts
> another Fixnum/Bignum, while the "*" operator for a String only  
> allows a
> Fixnum, because it sure doesn't let you do String * String (and why  
> would
> you really).
>
> Someone please help me grasp this :)     Thanks

You've got it I think. In the first instance you call the String#*  
method. This accepts an Integer argument and returns a String:

--------------------------------------------------------------- String#*
      str * integer   => new_str
------------------------------------------------------------------------
      Copy---Returns a new +String+ containing _integer_ copies of the
      receiver.

         "Ho! " * 3   #=> "Ho! Ho! Ho! "

The second time you call the Fixnum#* method which accepts Numeric  
arguments (not Strings).

--------------------------------------------------------------- Fixnum#*
      fix * numeric   =>  numeric_result
------------------------------------------------------------------------
      Performs multiplication: the class of the resulting object depends
      on the class of +numeric+ and on the magnitude of the result.

This being Ruby, it is easy (but maybe dangerous) to extend the  
Fixnum class to perform as you like:

irb(main):001:0> class Fixnum
irb(main):002:1> alias mult *
irb(main):003:1* def *(a)
irb(main):004:2> return a * self if a.is_a?(String)
irb(main):005:2> return mult(a)
irb(main):006:2> end
irb(main):007:1> end
=> nil
irb(main):008:0> 2 * 2
=> 4
irb(main):009:0> 2 * "foo"
=> "foofoo"

Alex Gutteridge

Bioinformatics Center
Kyoto University