I am struggling to understand when and when not to use symbols in Rails. I understand that symbols are not too dissimilar from a string without many of the methods. I also understand the symbols make good keys as symbols of the same name occupy one address in memory.
What I struggle to understand is why Rails decides to use symbols in some cases. If I had the callback
before_action :ask_stack_overflow_question
def ask_stack_overflow_question
puts "why did I just use a symbol?"
end
I don't quite understand why the treat the method as a symbol? Why would I need to keep a method constant?
I can't find any answer to this in the documentation.
Thank you
- RubyGuides What Are Ruby Symbols & How Do They Work? A symbol looks like this: Some people confuse symbols with variables, but they have nothing to do with variables… … a symbol is a lot more like a string. So what are the differences between Ruby symbols & strings? Strings are used to work with data. Symbols are identifiers.
… a symbol is a lot more like a string. So what are the differences between Ruby symbols & strings? Strings are used to work with data. Symbols are identifiers. That’s the main difference: Symbols are not just another kind of string, they have a different purpose.
The reason is that symbols were not garbage collected before Ruby 2.2, which means that they where not cleaned up from memory when no longer needed like regular Ruby objects (strings, hashes, arrays …). You will notice that the total count of symbols increases by 10, just like you would expect since we are creating 10 new symbols.
But since Ruby 2.2 these symbols are removed from memory because they are just temporary & not being used by something else in this code. If you try this code on a version of Ruby that has Symbol GC enabled both symbol counts will be the same. Some symbols will never be removed from memory, these are called “immortal symbols”.
This isn't as tricky as it seems.
When calling before_action
you do not want the method to be executed immediately, but you have to describe that action you want to have performed somehow. A symbol is used here to represent the name of the method to call.
So if this is captured as name
, then later, somewhere in the code, this is converted into a send(name)
at the appropriate time.
There's a big difference between these two. The immediate version is:
before_action method_name
Which has the effect of executing method_name
immediately, as Ruby will be compelled to run method_name
to find out what it returns, then pass that through to before_action
as an argument.
The deferred convention is:
before_action :method_name
Which is simply a polite request to before_action
, passing in a symbol as an argument. You're leaving it up to before_action
to deal with this however it sees fit, so it may or may not execute that method in the future, it depends on the situation.
This is how it works within Ruby with very few exceptions. The only one I can think of that doesn't immediately execute a method when it's specified immediately instead of as a representative symbol is the quirky alias
construct.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With