Ruby symbols

I keep seeing many programmers from different backgrounds are unable to get what Ruby symbols are, and though I do know that there are many great posts regarding this topic, and actually my intent is not to increase them by one :) , but I feel I have to clear few points regarding them.
So I’m trying to answer 2 important question here: What are Ruby symbols? and When to use them?

What are Ruby symbols?

Well, according to the API documentation:

Symbol objects represent names and some strings inside the Ruby interpreter. They are generated using the :name and :”string” literals syntax, and by the various to_sym methods. The same Symbol object will be created for a given name or string for the duration of a program’s execution, regardless of the context or meaning of that name. Thus if Fred is a constant in one context, a method in another, and a class in a third, the Symbol :Fred will be the same object in all three contexts.

Let’s walk over this long quote, point by point, but let’s first list all the points it has:

1-Symbol objects represent names and some strings inside the Ruby interpreter.
2-They are generated using the :name and :”string” literals syntax, and by the various to_sym methods.
3-The same Symbol object will be created for a given name or string for the duration of a program’s execution, regardless of the context or meaning of that name. Thus if Fred is a constant in one context, a method in another, and a class in a third, the Symbol :Fred will be the same object in all three contexts.

I’ll start with the 2nd point then get back to the rest, just before I do, please fire your irb:

We can create a symbol with various ways:

# Normal way, just prefix a token with ':'
greeting = :hi #=> :hi
 
# Multi token symbol 
another_greeting = :"hello man" #=> :"hello man"
 
# Use the .to_sym if it's defined for your object class
# For example .to_sym is defind in String class
a_third_greeing = "howdy".to_sym #=> :howdy
 
# Using %s[ ]
%s[a 4th one] #=> :"a 4th one"
 
# We can also cast a symbol to string with to_s
:ds.to_s #=> "ds"

That was the easy part, now let’s get back to the first point, it says: “Symbol objects represent names and some strings inside the Ruby interpreter.” , what does that mean exactly?

In computer science there is a term called: Symbol table, where the compiler or the interpreter of the language stores all the identifiers of a source code in that table to reference them -specifically to be referenced by the Abstract Syntax Tree(AST).
Actually the data structure that represents the symbol table varies from one interpreter to another, but what we care for is Ruby, in Ruby, the symbol table stores various things like method names and symbol names(we will check why Ruby does so later on), and the value of a symbol is a unique integer value, that can’t be changed.

# Not working on ruby 1.9
:ds.to_i #=> 28777
 
# Notice the value of the symbol is not its object id
:ds.object_id #=> 287778
 
# Symbol values can't be changed
:ds = 3 #SyntaxError: compile error

Now let’s take more in depth example, let’s explore the symbol table:

# Let's check what symbols names start with 'hello'
Symbol.all_symbols.collect{|x| x.to_s}.grep /^hello.*$/ #=> ["hello"]
 
# Now let's define a new dummy class and add  a new method called 'hello_world'
class Dummy; def hello_world; end ; end #=> nil
 
# Check again.
Symbol.all_symbols.collect{|x| x.to_s}.grep /^hello.*$/ #=> ["hello", "hello_world"]

As you can see, when we defined the class ‘Dummy’ and more specifically when we defined the ‘hello_world’ method, it was added to the symbol table.
Let’s take another example:

Symbol.all_symbols.size #=> 3329
:koko #=> :koko
Symbol.all_symbols.size #=> 3330

Now let’s take the last point : “The same Symbol object will be created for a given name or string for the duration of a program’s execution, regardless of the context or meaning of that name. Thus if Fred is a constant in one context, a method in another, and a class in a third, the Symbol :Fred will be the same object in all three contexts.” ,so: Fred is :Fred wherever you see it and no matter what the context it comes in:

k = :Fred  #=> :Fred                  
module M; Cons = :Fred; end #=> :Fred
k.object_id #=> 287498
M::Cons.object_id #=> 287498

When to use Ruby symbols?

Well, this might be the one million dollars question, and that’s initially why i wrote this post for. You also might be wondering, why have Matz chosen to give us this low level introspection in the language by allowing me to work with the interpreter stuff?

The answer is divided in 2 parts:

1- Efficiency. 2- Metaprogramming(reflection).

Efficiency

We will talk about efficiency at first place,so let’s check this snippet of code:

# Some programmer would do this
if name == "khaled alhabache"

The snippet of code above is really costive, in terms of memory and efficiency:
1-Comparing 2 strings is costive, specially when the 2 strings are long.
2-Reserving “changeable” amount of memory, 16 bytes in our case to instantiate “Khaled alhabache”.
3-The GC would have to clean this “Khaled alhabache” later on.

What about doing :

# This is what i call it "a cleaner approach"
if name.to_sym == :"khaled alhabache"

Now what we did is:
1-Comparing 2 integers(the value of a symbol is integer) which is cheaper.
2-Reserving memory 4 bytes for :”Khaled alhabache” symbol, cause a symbol is an integer finally.
3-The GC would not have to clean this :”Khaled alhabache” symbol, cause symbols don’t get deleted till program exits.

So use symbols as much as you can, and avoid using stings as much as you can, but take extra care of defining thousands of symbols, cause as mentioned: symbols don’t get deleted till program exits, and thus they stick in memory.

Metaprogramming and symbols

Well working with metaprogramming in Ruby is really nice, you can do something like:

to = [:to_s , :to_f , :to_r] #=> [:to_s, :to_f, :to_r]
 
# Notice the use of symbols with reflection -Ex with 'send' method 
to.each{|method| puts "#{method} => #{5.send method}"}
# to_s => 5
# to_f => 5.0
# to_r => 5

Without symbols, you would never be able to use reflection techniques like ‘send’, otherwise how can you invoke methods dynamically?, also without symbols, you would never be able to use introspection techniques like ‘respond_to?’

5.respond_to? :slice #=> false
5.respond_to? :to_f #=> true

Update, a respond to readers comments:
It’s true that you can do something like :

5.respond_to? "to_f" #=> true

But what’s happening is that Ruby is casting it for you, but why to reserve extra memory to send it as a string?

For guys who are objecting on memory efficiency with symbols, I strongly recommend reading this post also.

I hope I could help you understand what Ruby symbols are and why they are used for, specially of you who are coming from other programing backgrounds.

This entry was posted in Ruby and tagged , . Bookmark the permalink.

48 Responses to Ruby symbols

  1. Emmanuel Oga says:

    I’m not sure about using


    if name.to_sym == :"khaled alhabache"

    …always. I guess it depends on where does the name var come from. If I’m going to have thousands of never-garbage-collected symbols, maybe I could be introducing a “memory leak” by using them too sparingly.

    Also, you can do things like


    5.respond_to? "slice"

    that is, using strings instead of symbols, but you are right, ruby converts strings into symbols for that kind of operations anyway:


    Symbol.all_symbols.length # => 8495
    1.respond_to?("caracatisqui") # => false
    Symbol.all_symbols.length # => 8496

  2. John says:

    respond_to? and send respond to strings, so technically symbols are not required to call those methods.

  3. khelll says:

    @ Emmanuel Oga, then if so, it’s better that you have the name var as a symbol by default, instead of having it as a string and then casting it name.to_sym.
    As for the second part of your question, you are right, ruby will cast “caracatisqui” to a symbol, but why even to reserve a memory for sending it as a string? why not to use the symbol directly?

  4. khelll says:

    @ John, if you had a look at the Object API documentation, you will notice that the ‘send’ method receives a symbol, not a string, but ruby casts it for you.
    So technically it’s not required, but why to reserve an extra memory to ‘send’ a string, while you can use a symbol directly.
    Then it’s all about efficiency….

  5. nico says:

    In ruby 1.9 :ds.to_i gives a NoMethodError

  6. khelll says:

    @ nico, true, that won’t work, thanks for mentioning it.

  7. Glenn Gillen says:

    The GC would not have to clean this :Khaled alhabache symbol, cause symbols don’t get deleted till program exits.

    How is that considered considered a more efficient use of memory? The same result as interpreted from others has been:

    Let’s start off with memory. Every symbol is a memory leak. I don’t know who said that first, but it’s a great way to think about symbols. Every symbol lives forever

    from Josh Susser

    A Ruby symbol is a memory leak. Because of the way Ruby symbols are stored, they can never be garbage collected. So if we create 10,000 one-off symbols that will never use again, will never get the memory back.

    from Eric Kidd

    I’m sure there are scenarios where this might well be the case, but they’d need to be carefully thought out and measured with real world performance. I would think in the vast majority of cases that leaving these objects sitting around stale in memory is less than optimal.

  8. khelll says:

    @ Glenn Gillen, you are totally true, that’s why i said:

    So use symbols as much as you can, and avoid using stings as much as you can, but take extra care of defining thousands of symbols, cause as mentioned: symbols don’t get deleted till program exits, and thus they stick in memory.

  9. khelll says:

    For guys who are objecting on memory benefits, please have a look at this article

  10. Apostlion says:

    A symbol is not a memory leak. A symbol is a memory saver.

    What’s GC, really?

    Say, you create a hash as in Glu.ttono.us article listed above, {“abubu” => “ububa”}, and create another hash, oddly enough, also {“abubu” => “ububa”}. Well, four strings created, and if you delete the first hash, GC will kill two strings for ya.

    If using symbols, you don’t have those extra strings to delete anyway.

    And no matter how long your program runs, or whatever fancy loops and hoops it does, if you’re not dynamically creating symbols via #to_sym, only those specific, unique symbols you’ve explicitly named in your code will live. 1Mb memory leak is around 260k such symbols can you even imagine that many symbol names?

    As Khaled said, you’re ok unless you start dynamically creating thousands of symbols somewhere.

  11. Jack says:

    My fave use for symbols in Ruby, actually, is for uses roughly equivalent to use cases for “enum” in C: when passing mnemonic codes around between different scopes (something beyond simple “true” and “false”). Practically that’s likely to be similar to metaprogramming but a bit simpler. For example, you might have:


    def submit_button(caption, type=:input)
    # Code for :input, :button, :image, :a_with_onclick or whatever
    end

    …or there’s the slightly more familiar approach of the options hash:


    def add_column(name, type, default_value=nil, options={})
    # code which checks for options[:not_null], options[:key], options[:constraint],
    # options[:comment] et cetera.
    end

  12. Dan Mayer says:

    Good post I never really knew why people were pushing to use symbols over strings all the time. The best explanation before this I had heard was that Symbols where ‘lighter weight’ strings. I have used them all the time with out really fully getting it.

  13. Twitter says:

    This is my third time here, just thought I would mention that you are doing a great job

  14. i love to play all day on my gamecube. ,`*

  15. A formidable share, I just given this onto a colleague who was doing somewhat analysis on this. And he in reality bought me breakfast as a result of I found it for him.. smile. So let me reword that: Thnx for the deal with! But yeah Thnkx for spending the time to debate this, I really feel strongly about it and love reading extra on this topic. If possible, as you turn out to be expertise, would you mind updating your weblog with more details? It’s extremely helpful for me. Huge thumb up for this weblog submit!

  16. annunci says:

    There are some interesting closing dates on this article however I don’t know if I see all of them middle to heart. There may be some validity but I will take maintain opinion till I look into it further. Good article , thanks and we would like more! Added to FeedBurner as well

  17. tutto gratis says:

    Excellent weblog right here! Also your web site quite a bit up very fast! What host are you using? Can I am getting your affiliate hyperlink for your host? I want my site loaded up as quickly as yours lol.

  18. A lot of thanks for all of your hard work on this blog. My mother take interest in carrying out internet research and it’s really obvious why. A number of us learn all about the lively means you convey functional techniques through the blog and as well as welcome participation from others on this article and our girl has always been discovering a lot. Have fun with the remaining portion of the new year. You’re carrying out a really great job.

  19. of course like your website however you need to take a look at the spelling on quite a few of your posts. Many of them are rife with spelling problems and I find it very bothersome to tell the truth however I’ll certainly come back again.

  20. arcopedico says:

    What i do not understood is in reality how you are not actually a lot more neatly-appreciated than you might be now. You are very intelligent. You know thus considerably when it comes to this matter, made me personally believe it from a lot of numerous angles. Its like men and women don’t seem to be involved until it is one thing to accomplish with Lady gaga! Your own stuffs outstanding. At all times take care of it up!

  21. What’s Going down i am new to this, I stumbled upon this I have found It absolutely useful and it has aided me out loads. I hope to give a contribution & help different customers like its helped me. Good job.

  22. I’m often to running a blog and i actually admire your content. The article has really peaks my interest. I am going to bookmark your website and maintain checking for brand new information.

  23. Wonderful work! That is the kind of info that should be shared around the net. Shame on Google for no longer positioning this post upper! Come on over and visit my web site . Thank you =)

  24. wimax says:

    Useful information. Lucky me I found your site accidentally, and I am stunned why this accident didn’t took place in advance! I bookmarked it.

  25. It’s really a cool and useful piece of info. I am happy that you shared this useful info with us. Please stay us up to date like this. Thanks for sharing.

  26. city guides says:

    I have been browsing online more than three hours these days, but I never discovered any fascinating article like yours. It’s beautiful price enough for me. In my view, if all website owners and bloggers made just right content material as you probably did, the internet will be much more useful than ever before.

  27. rv repair says:

    I don’t even understand how I ended up right here, however I assumed this put up used to be great. I don’t understand who you might be but definitely you’re going to a famous blogger if you happen to are not already ;) Cheers!

  28. Google says:

    I must get across my respect for your kind-heartedness for folks that really want help with this particular content. Your real dedication to getting the message up and down came to be remarkably practical and has specifically enabled guys and women just like me to get to their aims. Your new warm and friendly report can mean much to me and still more to my office colleagues. Thank you; from each one of us.

  29. An interesting discussion is worth comment. I feel that you need to write extra on this subject, it may not be a taboo subject but usually individuals are not enough to speak on such topics. To the next. Cheers

  30. A formidable share, I simply given this onto a colleague who was doing slightly analysis on this. And he in reality purchased me breakfast as a result of I found it for him.. smile. So let me reword that: Thnx for the deal with! However yeah Thnkx for spending the time to debate this, I really feel strongly about it and love reading extra on this topic. If attainable, as you turn into experience, would you thoughts updating your blog with more details? It is highly useful for me. Massive thumb up for this weblog submit!

  31. you are in point of fact a excellent webmaster. The site loading pace is amazing. It kind of feels that you’re doing any unique trick. Also, The contents are masterpiece. you have performed a fantastic process in this topic!

  32. Great information over again. I am looking forward for your next post=)

  33. It’s onerous to search out educated people on this subject, however you sound like you recognize what you’re speaking about! Thanks

  34. Fantastic web site. Plenty of helpful info here. I’m sending it to several buddies ans also sharing in delicious. And certainly, thank you in your effort!

  35. rock dating says:

    It’s actually a great and helpful piece of information. I’m happy that you shared this useful information with us. Please keep us informed like this. Thanks for sharing.

  36. Hairdressers says:

    Normally I don’t read post on blogs, but I wish to say that this write-up very compelled me to take a look at and do it! Your writing taste has been amazed me. Thanks, quite great article.

  37. Hmm it appears like your site ate my 1st comment (it was super long) so I guess I’ll just sum it up what I had written and say, I’m thoroughly enjoying your blog. I as well am an aspiring blog blogger but I’m nonetheless new to everything. Do you have any points for novice blog writers? I’d undoubtedly appreciate it.

  38. I simply wanted to say thanks yet again. I’m not certain the things I would’ve taken care of in the absence of the entire smart ideas contributed by you over that problem. It was before an absolute depressing circumstance in my circumstances, nevertheless looking at the very skilled technique you dealt with it made me to jump with happiness. Extremely grateful for this advice and trust you comprehend what an amazing job you happen to be getting into educating some other people through a site. I know that you haven’t got to know any of us.

  39. Ben Rutledge says:

    My name is Danial Lynch. Could u add a backlink on this page? You can reach me at LorenzoWest5688@yahoo.com or ICQ:943264932

  40. Heya i am for the primary time here. I found this board and I to find It truly helpful & it helped me out much. I am hoping to provide one thing back and help others such as you helped me.

  41. hello!,I love your writing so a lot! percentage we be in contact extra approximately your post on AOL? I need an expert on this house to unravel my problem. Maybe that’s you! Taking a look forward to look you.

  42. ecu says:

    F*ckin’ tremendous things here. I am very glad to look your post. Thanks a lot and i’m taking a look ahead to touch you. Will you kindly drop me a mail?

  43. codes color says:

    You made some first rate factors there. I seemed on the web for the problem and located most individuals will associate with together with your website.

  44. laptops says:

    I appreciate your wp web template, wherever do you down load it through?

  45. Oh my goodness! a tremendous article dude. Thanks Nevertheless I’m experiencing problem with ur rss . Don’t know why Unable to subscribe to it. Is there anybody getting an identical rss drawback? Anybody who is aware of kindly respond. Thnkx

  46. I together with my friends have already been examining the excellent techniques found on your web blog and quickly I got a horrible feeling I had not thanked you for those tips. These ladies came consequently thrilled to learn them and have now extremely been enjoying those things. Thank you for really being well considerate and also for opting for variety of great tips most people are really eager to know about. My personal honest apologies for not expressing gratitude to you earlier.

  47. My husband and i ended up being lucky Emmanuel managed to do his investigations by way of the precious recommendations he made through your site. It is now and again perplexing to just be giving for free tricks that some others might have been selling. We fully understand we have got the blog owner to give thanks to because of that. The most important explanations you’ve made, the simple website menu, the relationships you will help to promote – it’s everything excellent, and it is assisting our son and our family reckon that this theme is brilliant, which is certainly unbelievably important. Thank you for all the pieces!

  48. Whoah this blog is great i really like reading your articles. Keep up the great paintings! You know, lots of persons are looking around for this information, you can help them greatly.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">