This question already has answers here:
Define custom Ruby operator
(3 answers)
Closed 9 years ago.
I would like to be able to define custom operators. Is that possible? For example, to make a***b mean something.
Is it also possible to monkey patch existing operators? To, for example, make a**b always return a float?
Yes, you can. For example:
class Fixnum
def **(x)
self.*(x)*1.0
end
end
5**4 #==> 20.0
Custom operators? Not unless you want to hack the C parser (or Java parser for JRuby or ...). OTOH, operators are mostly syntactic sugar for methods and you're allowed to defined all the methods you want.
Since many operators (but not all) are just methods in disguise, you can monkey patch the implementations of existing operators as much as you want to. You'd have to track down all the numeric classes that define their own ** implementation and patch all of them; note that you'd need to cover Rational, Complex, ... from the core as well as things like BigDecimal from the standard library. I'd strongly recommend against doing this, you'd just be setting yourself up for pain and suffering; for example, what would you do with BigDecimal#** when the result doesn't fit in a Float? What about Complex#**? If you need Floats for something, make it explicit with a to_f call.
Related
In Ruby, there is a convention to have a method name end with a question mark to indicate that its return value is boolean. Why is boolean considered so special? Is there anything convenient if you know that a method's return value is particularly boolean? After all, in Ruby, you can insert all kinds of value returning (getter) methods into a conditional without caring whether it is boolean or not.
I think it is a waste to use the question mark just for indicating a boolean value. There should be more useful uses. I have plenty of use case where I want to have a pair of getter and setter methods, where the setter method should return self so that I can use it in a method chain. And naming them something like get_foo and set_foo looks cumbersome. Rather than following the convention, I am tempted to name a pair of getter and setter methods like this:
def foo?; #foo end
def foo v; #foo = v end
where the value of #foo is not (necessarily) boolean. (Besides potential criticism that breaking the convention will confuse other programmers), is there something wrong with doing that?
There is nothing special at all, it's just a convention. A question can be answered with "yes" or "no", but also with another stuff like someone's name.
By returning a boolean on methods with a question mark, it indicates it to be an explicit behavior.
If you make the answer be "yes" or "no", it's easy for the reader of your code to identify the behavior of your method without even looking at the implementation. On the other hand, if you make it return any other type, it is more difficult for the reader to understand your code without reading your class and method definition.
With a boolean there are only two possible answers. If the return value is not boolean it can be anything, which would not help at all. You would still need to look at the method implementation. You should always look further to understand some piece of code, but using this convention makes it simpler.
There is a convention to use question mark in method names to indicate that a method is a predicate. AFAIK, this predicate is not required (by the convention) to return a boolean value, thanks to simple rules for truthy/falsey values.
Besides potential criticism that breaking the convention will confuse other programmers, is there something wrong with doing that?
Confusing and surprising fellow programmers is bad. Ruby couldn't care less. It's just a convention. And conventions exist for a reason.
You can put anything in a flow control construct, but semantically booleans are appropriate. "If" in real human language typically takes a boolean, and the same is true of the construct in many programming languages. Ruby likes to make things convenient and assigns a "truthiness" value to everything in the language, which affects how it behaves in a boolean context.
In other words, booleans are the only things that are almost exclusively used for flow control, so the convention is to make them look "right" for flow-control constructs. It's their native environment.
(Besides potential criticism that breaking the convention will confuse other programmers), is there something wrong with doing that?
In the same sense that there is nothing wrong with naming all your variables after 1920s comedians, no, there's nothing wrong with that. But also in the same sense as naming all your variables after 1920s comedians, it isn't a very good idea. Nowhere in any language that I know of -- human or computer -- does the question mark mean "get." So the semantics of your code are off with that convention.
This question and the answers boil down to "POLS" AKA "Principle of Least Surprise".
A method name can be a random choice of letters and numbers separated by underscores, with '!', '?' and '=' sprinkled through them, if we chose to do so. They could be randomly created by the code at run time, and, as long as the rest of the code used the same arrangement of characters, the program would run and Ruby would be happy.
We humans, the programmers, determine the name of the methods used, to represent something, a characteristic or an action. Trying to use randomly named methods would lead to madness, or at least a very hard to maintain program. So, instead, we try to use sensible names for things. Sometimes they're verbs or adjectives, sometimes they're more descriptive because the method does several things.
As part of that naming, sometimes we want to provide additional hints about the behavior of the method. By convention in Ruby, we use "!" to warn the coder that the method changes something or is destructive. "=" indicates the method takes a parameter and assigns it to the receiver/object. It's a setter method and in many other languages it'd be idiomatic to use "set_flag..." or "set_value..." as the name. It's just a convention in that language, and followed by developers in the language.
We use "?" in Ruby to ask a question about an object, whether it is, or isn't, true about that object. We could say "is_true?" or "true?" and indicate we are testing whether something is true about it. If it's true, or false, it's a Boolean response so we return a true/false value.
In my last Question I was looking for a way to extend the abilities of Ruby-variables. Answering this lead me to a new question. Apparently "monkey patching" is what solved a huge chunk of that problem, now I can at least do my typing indirectly with something along the lines of (a = 3).nat where nat is a method "monkeypatched" into Fixnum checking weather "3" is a valid value. This is ok for a start but still a bit clumsy and unintuitive. What I really need in the end is a way to rewrite, extend, intercept or overload to constructor for Fixnum so that a = 3 directly calls the method nat.
Is there a way to do this?
I am not only interested in a "proper way", it can be a bit "hacky". This is only for my research, it can be a dangerous, unsupported way.
In your example a constructor is not called, what is happening is that you are making a a reference to the literal 3 through the use of the assignment operator =.
What you want is to overwrite assignment which is not possible AFAIK.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the difference between Ruby 1.8 and Ruby 1.9
I have found some differences in interpretation of global and local variables.
Can anyone point me to list of major differences?
These are probably the most important changes:
Ruby 1.9 changed from being
interpreted to being
bytecode-compiled (using the YARV
VM).
The String class has been redesigned
entirely to make it encoding-aware.
Regular expressions are now
implemented using the Oniguruma
engine, rather than the home-made one
used in ruby 1.8, enabling new
features like negative look-around.
The enumerator library from stdlib
has been added to core and most
Enumerable methods have been
changed to return an Enumerator
when invoked without a block.
Symbol#to_proc has been added.
There's a new syntax for lambdas,
-> which allows default arguments
and lambdas taking blocks.
There's a more complete list of changes here.
One major point might be that they use a different VM (at least, the 'standard' distributions do, obviously there are a number of options like MacRuby, IronRuby, etc). You might have a look here for details on all the changes.
"Everything is an object" was one of the first things I learned about Ruby, but in Peter Cooper's Beginning Ruby: From Novice to Professional, it is mentioned that "almost everything in Ruby is an object".
Can you give me some examples of things that are not objects in Ruby?
The most obvious one that jumps into my head would be blocks. Blocks can be easily reified to a Proc object, either by using the &block parameter form in a parameter list or by using lambda, proc, Proc.new or (in Ruby 1.9) the "stabby lambda" syntax. But on its own, they aren't objects.
Another example are operators.
if
else
{
}
general language constructs, etc...
I think pretty much everything else (including methods) are objects.
After splitting the script into meaningful tokens by the lexer, everything is an object. Including classes. Even literal constants like 1 are objects. Some objects may have a syntax that is not purely OO (i.e. syntactic sugar) but that's mostly for easy manipulation more than anything. Blocks are not strictly objects though (but can as someone said be converted into one).
In the case of variable assignment, i.e.
product = 5 * 5
the variable is not an object... so add that to the list
According to Wikipedia, a monkey patch is:
a way to extend or modify the runtime
code of dynamic languages [...]
without altering the original source
code.
The following statement from the same entry confused me:
In Ruby, the term monkey patch was
misunderstood to mean any dynamic
modification to a class and is often
used as a synonym for dynamically
modifying any class at runtime.
I would like to know the exact meaning of monkey patching in Ruby. Is it doing something like the following, or is it something else?
class String
def foo
"foo"
end
end
The best explanation I heard for Monkey patching/Duck-punching is by Patrick Ewing in RailsConf 2007
...if it walks like a duck and talks like a duck, it’s a duck, right? So
if this duck is not giving you the noise that you want, you’ve got to
just punch that duck until it returns what you expect.
The short answer is that there is no "exact" meaning, because it's a novel term, and different folks use it differently. That much at least can be discerned from the Wikipedia article. There are some who insist that it only applies to "runtime" code (built-in classes, I suppose) while some would use it to refer to the run-time modification of any class.
Personally, I prefer the more inclusive definition. After all, if we were to use the term for modification of built-in classes only, how would we refer to the run-time modification of all the other classes? The important thing to me is that there's a difference between the source code and the actual running class.
In Ruby, the term monkey patch was
misunderstood to mean any dynamic
modification to a class and is often
used as a synonym for dynamically
modifying any class at runtime.
The above statement asserts that the Ruby usage is incorrect - but terms evolve, and that's not always a bad thing.
Monkey patching is when you replace methods of a class at runtime (not adding new methods as others have described).
In addition to being a very un-obvious and difficult to debug way to change code, it doesn't scale; as more and more modules start monkey patching methods, the likelihood of the changes stomping each other grow.
You are correct; it's when you modify or extend an existing class rather than subclass it.
This is monkey patching:
class Float
def self.times(&block)
self.to_i.times { |i| yield(i) }
remainder = self - self.to_i
yield(remainder) if remainder > 0.0
end
end
Now I imagine this might be useful sometimes, but imagine if you saw routine.
def my_method(my_special_number)
sum = 0
my_special_number.times { |num| sum << some_val ** num }
sum
end
And it breaks only occasionally when it gets called. To those paying attention you already know why, but imagine that you didn't know about the float type having a .times class-method and you automatically assumed that my_special_number is an integer. Every time the parameter is a whole number, integer or float, it would work fine (whole ints are passed back except when there is a floating-point remainder). But pass a number with anything in the decimal area in and it'll break for sure!
Just imagine how often this might happen with your gems, Rails plugins, and even by your own co-workers in your projects. If there's one or two little methods in there like this and it could take some time to find and correct.
If you wonder why it breaks, note that sum is an integer and a floating-point remainder could be passed back; in addition, the exponential sign only works when types are the same. So you might think it's fixed, because you converted bother numbers to floats ... only to find that the sum can't take the floating-point result.
In Python monkeypatching is referred to a lot as a sign of embarrassment: "I had to monkeypatch this class because..." (I encountered it first when dealing with Zope, which the article mentions). It's used to say that it was necessary to take hold of an upstream class and fix it at runtime instead of lobbying to have the unwanted behaviors fixed in the actual class or fixing them in a subclass. In my experience Ruby people don't talk about monkeypatching that much, because it's not considered especially bad or even noteworthy (hence "duck punching"). Obviously you have to be careful about changing the return values of a method that will be used in other dependencies, but adding methods to a class the way that active_support and facets do is perfectly safe.
Update 10 years later: I would amend the last sentence to say "is relatively safe". Extending a core library class with new methods can lead to problems if somebody else gets the same idea and adds the same method with a different implementation or method signature, or if people confuse extended methods for core language functionality. Both cases often happen in Ruby (especially regarding active_support methods).
Explanation of the concept without code:
It means you can "dynamically" modify code. Wanna add a method "dynamically" to a particular class known only at "runtime"? No problem. It's powerful, yes: but can be misused. The concept "dynamically" might be a little too esoteric to understand, so I have prepared an example below (no code, I promise):
How to monkey patch a car:
Normal Car Operations
How do you normally start a car? It’s simple: you turn the ignition, the car starts!
Great, but how can we "monkey patch" the car class?
This is what Fabrizzio did to poor Michael Corleone. Normally, if you want to change how a car operates, you would have to make those changes in the car manufacturing plant (i.e. at "compile" time, within the Car class ^**). Fabrizzio ain't got no time for that: he monkey patches cars by getting under the bonnet to surreptitiously and sneakily rewire things. In other words, he re-opens the Car class, makes the changes he wants, and he's done: he's just monkey patched a car. he done this "dynamically".
You have to really know what you are doing when you monkey patch otherwise the results could be quite explosive.
“Fabrizzio, where are you going?”
Boom!
Like Confucius Say:
"Keep your source code close, but your monkey patches closer."
It can be dangerous.
^** yes i know, dynamic languages.
Usually it is meant about ad-hoc changes, using Ruby open classes, frequently with low quality code.
Here's a good follow-up on the subject.