Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The commutative property of multiplication in Ruby

Tags:

ruby

In ruby, I was messing around in the irb and found two code samples that should work the same but don't

"a" * 4     #this is "aaaa"
4 * "a"     #this is "String can't be coerced into a Fixnum"

Doesn't this violate the commutative property of multiplication?

like image 250
Michael Avatar asked Mar 15 '16 01:03

Michael


1 Answers

It does violate the commutative property, but that's not necessarily a problem, as the commutative property applies to the complex complex numbers in math. The reason "a" * 4 is not commutative in Ruby, as in most programming languages, is because a given type defines how it handles operators. So you could override the * operator for the String and Fixnum class (but that's a VERY VERY bad idea in practice):

class String
    def *(other)
        if other.is_a?(Numeric)
            puts "The method was called on an instance of String"
        end
    end
end

class Fixnum
    def *(other)
        if other.is_a?(Numeric)
            puts "The method was called on an instance of Fixnum"
        end
    end
end

So if you were to call

"a" * 4

Then it would print "The method was called on an instance of String" because that is equivalent to "a".*(4)

But this:

4 * "a"

Would print "The method was called on an instance of Fixnum" because 4 * "a" is equivalent to 4.*("a")

Here is a good article on operator overloading in Ruby.

Interesting side note: the commutative property actually doesn't apply to all numbers in math, the Quaterions and the Octonions both are not commutative.

Edit

If you wanted to, you could make the * operator commutative (but that would be a bad idea). You could then define * to swap the callee and the argument like such:

class Fixnum
    def *(other)
        other * self
    end
end

That way, when ever you have 4 * "a" it would actually do this: "a" * 4. This would still work even if String#* was later redefined. Monkey patching can often be useful, but in this case it's a terrible idea, I don't recommend doing this, it's just a cool proof of concept.

like image 162
Addison Avatar answered Oct 09 '22 04:10

Addison