Is there a good guideline for static method vs. instance method distinction?
a.inverse() -> mutates 'a' to its inverse
MatrixMath.inverse(a) -> returns the inverse of 'a', leaving 'a' unchangedBTW the ruby equivalent for the above convention would be (maybe inspired by scheme?)
a.inverse!() -> mutate a
a.inverse() -> return the inverse
Which one is more consistent? 1 isn't a matrix
A Fixnum could be interpreted as a 1x1 matrix. For some recursive solutions, it would probably be nice of MatrixMath.inverse accepted it as such, as well as [[1]].However, it doesn't take much to "fix" it the way you like it. You need to patch Numeric. Whenever you call a method that doesn't exist, it calls the method "method_missing". Hence you can monkey patch Numeric#method_missing to call the equivalent Math function.
In ruby you dont. It's #size and ruby is quite consistent in this respect. So it's remembering a method name vs remembering a function name (in a supposedly OO language).
It's part of the Ruby's philosophies to have synonyms like that.
Example: If __len__ is defined on an object x, and __nonzero__ (Py2) or __bool__ (Py3) is not defined, then "not x" will test if x.__len__() == 0.
Similarly, __contains__ interacts with "foo in x", and __eq__ and __hash__ are expected to play well together for hashable objects (e.g. unique members of a set).
The double underscores are a useful code smell that indicates you're changing how an object interacts with Python's syntax.
I still think it's the wrong design, mind you, but I no longer think it's a crazy one.
Why use x.__len__() rather than len(x)?