A guide to understanding Ruby better
Helpful Command-Line Flags
The -c
and -w
command-line flags for ruby mean check for syntax errors and check for questionable Ruby, respectively.
ruby -cw program.rb
The difference between “load” and “require”
Semantically speaking, you load a file, but you require a feature. Also, require doesn’t reload files, but load does, if it’s called again.
Double exclamation
Use double exclamation points to check if an object is not nil.
Understanding Ruby object message
In Ruby, all values and data structures are objects. 1
, @dog
, and ["blog"]
are objects
even though they are instances of different classes. Every object also understands a set
of messages. To send an object a message, use the dot operator to the right of the object
and type the message. For example
After the message is sent to the dog object, the corresponding method is called. So far, this seems like really complicated talk for the simple concept of calling a method, but it is necessary.
For example, you might send an object a message that doesn’t correspond to a method. But due to Ruby’s introspective powers, you can intercept that message and call some other methods. That’s what libraries in Ruby on Rails do. ActiveRecord uses message interception to determine the corresponding database columns it should look at.
Did I have to define a method find_by_user_id
? Nope, ActiveRecord intercepts the message find_by_user_id
. It then parses it and sees
that I’m trying to find by the user_id
table column, and it fetches the records with the matching columns. See how such the simple concept of message
interception can lead to powerful results?
The difference between instance method and method
Search for a method
I sometimes switch from programming in C# to Python to Java to Ruby (not all in one day!). Just like learning Spanish and Italian, it’s easy to mix up which word belongs to which language. In the case of programming languages, it’s easy to forget, does a String
class in Ruby use the length
or size
method? Use the following snippet to search for methods within a class.
The code above says for the String
class, return to me all instance methods and don’t give me the ones that it’s inherited from ancestor classes. Within that array of instance methods, find a symbol that contains the word size or the word length.
Fortunately, since one of the core principle’s of Ruby’s philosophy is to make programmers happy, Ruby contains both String#size
and String#length
.
Ruby’s private
keyword
Ruby’s private
keyword is different from C++ and Java’s private keyword. The “private rule”,
from Paolo Perrotta’s excellent Metaprogramming Ruby: Program Like the Ruby Pros, states that
a private
method comes about from two rules acting together
-
in order to call a method on an object that is NOT yourself, you need to specify explicitly the receiver
-
private
methods can only be called with an implicit receiver
As a corollary, you can’t call a private
method on an object even with self
as the explicit receiver.
Let’s see this rule in action:
Why couldn’t we call disassociate_from_other_dogs
on dog
? Let’s apply the rule! self
, refers to main
, so the object dog
is not yourself. Thus, in order to call a method on dog, we need to specify the receiver explicitly.
Okay, we’ve specified we’re calling the method on dog. However, disassociate_from_other_dogs
is a private
method. According to the second rule, private
methods can only be called with an implicit receiver. But we’re explicitly specifying the object. So why don’t we implicitly specify the object is dog
? We can’t because self
refers to main
. Thus, we can’t call the private
method on dog
.
There is a way to call an object’s private
method: simply use the Object#send
method that all objects inherit.
But this violates the rule! Honestly, I don’t know what to make of this, but it seems the Ruby core contributors don’t either.