Below you will find pages that utilize the taxonomy term “Why I Like Ruby”
why i like ruby 1 alias_method
So you found yourself in the need to override a method but still count on it's old behaviour?
No problem! Override it with your new code, call super and.... Uh oh!! Suddenly this turned into a problem... Let me give some more context.
I was testing Ferret (and the acts_as_ferret plugin) in a project to provide full text search capabilities to our models. One of the things the plugin does is to add a new method to ActiveRecord, called find_with_ferret. That way, every model can use it. Great!
So I thought that would make sense for me to remove all diatrictics from the input text before letting ferret do its job. You know, like removing umlauts and all that.
I could do that by overriding this method with code to remove the undesired chars and then call its older version to finally do the search - something like calling super, but not quite. And I didn't want my models to inherit from anything else than ActiveRecord::Base. That wouldn't make any sense.
alias_method to the rescue!
You know that to redefine a method in an existing class you can open it up and rewrite it. But since you don't wanna loose the behaviour provided by the original method, this is how you can achieve this:
module ActiveRecord
class Base
alias_method :find_with_ferret_original, :find_with_ferret
def find_with_ferret(q, options = {}, find_options = {})
remove_diatrictics!(q)
find_with_ferret_original(q, options, find_options)
end
end
end
And you're good to go. On line 3 you're just giving the original method an alias, making a copy of it.
Then you redefine it the way you like and on line 6 you call the old version to make sure u still got the same behaviour.
Now all my models can benefit of this change without requiring them to call another method nor inherit from another class.
Cool, huh? :)
why i like ruby or ruby the language of the lazy programmer
This is quite funny. A friend, Perl addicted, is now learning Ruby. He really enjoys the language but made a interesting observation: Ruby is a language for lazy programmers!
Well, I have to agree... You know, I love saving keystrokes and achieving more by writing less. And this is so true with Ruby.
Let me give a really simple example, comparing with java - don't get me wrong... I love java, specially the platform, but it fits well here since I've always been a Java guy.
Imagine you have a Phone class with the attributes number and type, which can indicate whether the phone is a land line or a mobile phone. Then you got an array filled with phone classes and you want to narrow it by creating a new array only with mobile phones.
In Java, such a class could look very much like this:
public class Phone {
private String number;
private String type;
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Quite simple, isn't it? But we are telling the compiler many things we actually shouldn't need to. This class is a java bean and as such, among other things, it needs a pair of getters and setters for each of its attributes.
Now, on with our example, the same class, in ruby, looks like this:
class Phone
attr_accessor :number, :type
end
Yeah, I know the feeling. This class has exactly what we need: the two attributes with its own pairs of getters and setters each. But we didn't need to inform it in the verbose way Java has teached us. Cleaner, period.
Now to the code that actually returns the new array containing only mobile numbers. In java, we can do it in two different ways.
Using an ArrayList:
//Create two phone objects, one land line and one mobile
...
// Add them to an array
ArrayListphones = new ArrayList ();
phones.add(land);
phones.add(mobile);
//Return an array only with mobile numbers:
private static ArrayListselectMobilePhones(ArrayList phones) {
ArrayList<Phone> mobiles = new ArrayList<Phone>();
for (Phone phone : phones) {
if (phone.getType().equals("mobile")) {
mobiles.add(phone);
}
}
return mobiles;
}
Or using ordinary arrays:
// Assume the same phone objects here
...
//Add them to the array
Phone[] phones = new Phone[]{land, mobile};
//Return an array only with mobile numbers:
Phone[] mobiles = new Phone[a.length];
for (int i = 0; i < a.length; i++) {
if (a[i].getType().equals("mobile")) {
mobiles[i] = a[i];
}
}
And you're good to go. Actually this code with an ArrayList here only looks good thanks to generics. But this is another matter. Let's take a look at the ruby code that accomplishes de same task:
//Create two phone objects, one land line and one mobile
...
//Add them to an array
phones = [land, mobile]
//Return an array only with mobile numbers:
mobiles = phones.select { |phone|
phone.type == "mobile"
}
See the difference? Java is a great language but too verbose at times. This is a really simple example but if you take the same principle to a bigger app... yeah, you see where I'm going.
The bottom line... Ruby may be the language of the lazy programmer, as my friend pointed out. But I don't mind being called lazy as long as I can type less and be more productive. Do you? :)