(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

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

4 * "test "
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

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

Bioinformatics Center
Kyoto University

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

Fixnum, because it sure doesn’t let you do String * String (and why
would
you really).

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

Bioinformatics Center
Kyoto University

Dan wrote:

Just a small quick question:

String * Fixnum works:

while Fixnum * String doesn’t:

Think of it like this:
43 = 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

Dan wrote:

4 * "test "
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 P.'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!