(String * Fixnum) and (Fixnum * String)

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 :slight_smile: 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

···

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 :slight_smile: Thanks

------------------------------------------------------------------------
      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

To clarify my previous answer, the important thing is to realise that most 'operators' in Ruby are just methods that look funny. So

3 * 2

Is just another way of writing

3.* 2

or

3.send(:*,2)

And hence 'foo' * 2 is very different to 2 * 'foo' in terms of the underlying method that is called.
Alex Gutteridge

Bioinformatics Center
Kyoto University

···

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

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).

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 :slight_smile: Thanks

As I read it in Chris Pine's excellent 'How to Program', when you do string * fixnum, you're telling the string to multiply itself 'fixnum' times - the string knows how to do that.

When you do fixnum * string, you're trying to ask the a fixnum to multiply itself string times - that makes no sense. Thus, it's not allowed.

Cheers,
Mohit.
8/21/2007 | 3:00 PM.

P.S. I'm new to the group - so, I'll use this email to piggyback and say HI to everyone!

Dan wrote:

Just a small quick question:

String * Fixnum works:
...
while Fixnum * String doesn't:

Think of it like this:
4*3 = 4+4+4 (4 added 3 times) = 12
3*4 = 3+3+3+3 (3 added 4 times) = 12
Those are equivalent because x added y times and y added x times always give
the same result (x and y being numbers).

"bla"*3="bla"+"bla"+"bla" ("bla" added 3 times)="blablabla"
But what would 3 * "bla" be? 3 added "bla" times? What does that mean?

HTH,
Sebastian

···

--
NP: In Flames - System
Jabber: sepp2k@jabber.org
ICQ: 205544826