Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do callbacks use symbols in Ruby on Rails

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

like image 232
DWB Avatar asked Nov 06 '14 18:11

DWB


People also ask

What are Ruby symbols&how do they work?

- 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.

What is the difference between Ruby symbols&strings?

… 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.

Why are symbols not being garbage collected in Ruby?

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.

Why are some symbols removed from memory in Ruby?

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”.


1 Answers

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.

like image 155
tadman Avatar answered Nov 14 '22 21:11

tadman