Eloquent Ruby

Russ Olsen

Mentioned 18

Presents information on writing Ruby code, covering such topics as control structures, strings, expressions, building methods, classes, and domain specific languages.

More on Amazon.com

Mentioned in questions and answers.

As it stands now, I'm a Java and C# developer. The more and more I look at Ruby on Rails, the more I really want to learn it.

What have you found to be the best route to learn RoR? Would it be easier to develop on Windows, or should I just run a virtual machine with Linux?

Is there an IDE that can match the robustness of Visual Studio? Any programs to develop that give a good overhead of what to do? Any good books?

Seriously, any tips/tricks/rants would be awesome.

Fantastic decision! It is extremely useful to get a grounding in Ruby before going to Rails so here is my take on the best path to Rails:

Aside from books the most important thing is to get feedback on what you are doing. To do this I recommend spending time in irc.freenode.net #ruby and #rubyonrails. It is also extremely helpful to post things you are working on or having trouble with here on stackoverflow as the comments, explanations and different way of thinking about things that people provide are invaluable.

You should also definitely check out the Ruby Rogues podcast, they provide invaluable information and the commentators are all extremely respected people in the Ruby community. And for your viewing and reading pleasure (in that order,) head over to Ryan Bates's Railscasts and then Eifion Bedford's Asciicasts.

Finally, I recommend looking into different gems on github, reading the code and then contributing to them. You don't have to get overly ambitious and do massive recodes, especially at first. Just start with small things like editing and making the README files a little easier to read.

I don't use an IDE but at Railsconf I saw a demo of Rubymine from Jetbrains and it seemed pretty amazing.

I have a coworker who is actively trying to convince me that I should not use do..end and instead use curly braces for defining multiline blocks in Ruby.

I'm firmly in the camp of only using curly braces for short one-liners and do..end for everything else. But I thought I would reach out to the greater community to get some resolution.

So which is it, and why? (Example of some shoulda code)

context do
  setup { do_some_setup() }
  should "do somthing" do
    # some more code...
  end
end

or

context {
  setup { do_some_setup() }
  should("do somthing") {
    # some more code...
  }
}

Personally, just looking at the above answers the question for me, but I wanted to open this up to the greater community.

The most common rule I've seen (most recently in Eloquent Ruby) is:

  • If it's a multi-line block, use do/end
  • If it's a single line block, use {}

So I know the distinction between the bang (exclamation mark) and non-bang methods usually is whether the method will modify the object itself or return a separate modified object keeping the original unchanged.

Then while building the User model in chapter 6 of the book, I came across the User.create method, which creates a new model and saves it to the database in a single step. In Michael Hartl's Ruby on Rails 3 Tutorial, he writes that the User.create! method "works just like the create method...except that it raises an ActiveRecord::Record-Invalid exception if the creation fails."

I'm pretty confused. Is the User.create! method not following Ruby "bang-convention" or am I completely missing something? And if he IS following the convention, how does User.create! modify self if it is a class method?

Though a lot of classes treat bang methods as "a method that modifies the object in place", I like the description of bang methods from the Eloquent Ruby book better:

In practice, Ruby programmers reserve ! to adorn the names of methods that do something unexpected, or perhaps a bit dangerous

So in this case, the "unexpected" result is that an exception is raised instead of just failing and returning false.

I'm an advanced beginner/intermediate Ruby programmer. I'm really working on improving my Ruby skills, with specific focus on writing more efficient, compact, idiomatic Ruby, following solid testing practices, and learning and adhering to project structure and other general best practices.

With that in mind, I've been looking for good material to learn from. I've checked out a couple of the Play By Play Peepcode screencasts, which are great, but not exactly what I'm looking for. I've poked around Github, but most projects that I'm familiar with can be pretty sprawling--I spend far too much time unwrapping how things actually fit together and trying to build a mental model of things than I do actually spending time understanding the development process. So, I'm looking for good examples of quality projects/gems/libs that are compact, well-built, etc. I'd prefer something that's self contained, i.e., doesn't extend functionality of some other tool that I would first need to pick apart before being able to understand the 'extension'. Also, my focus here is Ruby development--not Ruby on Rails development. Any suggestions?

The best resource I've found is Eloquent Ruby by Rick Olsen, which is an in-depth guide to writing idiomatic Ruby, and the reasoning behind the choices made.

I have a HAML template that I want to render and optionally provide a local variable to, here called post, so that it either uses the provided variable as the value of an element attribute, or falls back to an explicit default.

The code below shows what I mean, but it fails to run if post isn't provided. Is there a clean solution to this? I have quite a few of these fields, and I'd rather not have to keep duplicating them with - if defined? statements, which is the only other alternative I can think of.

%label
  Post title
  %input{:name  => "title",
         :value => (defined? post) ? post.title : ""} }

Try this doing this:

%input{:name => "title", :value => post ? post.title : ""}

You don't need to check with defined because nil is treated as false in the Ruby interpreter. This excerpt from Eloquent Ruby by Russ Olsen describes it best:

In Ruby, only false and nil are treated as false. Ruby treats everything else--and I do mean everything--as true.

If this is a Rails app, a more eloquent solution would be to use the Rails try method:

%input{:name => "title", :value => post.try(:title)}

The try method invokes the method identified by the symbol that's passed in on the class unless the class itself is nil, in which case it will return nil (which haml will automatically convert to a blank string). Read more about the rails try method here.

I just started reading this book Eloquent Ruby and I have reached the chapter about Symbols in Ruby.

Strings in Ruby are mutable, which means each string allocate memory since the content can change, and even though the content is equal. If I need a mutable String in Java I would use StringBuffer. However since regular Java Strings are immutable one String object can be shared by multiple references. So if I had two regular Strings with the content of "Hello World", both references would point to the same object.

So is the purpose of Symbols in Ruby actually the same as "normal" String objects in Java? Is it a feature given to the programmer to optimize memory?

Is something of what I written here true? Or have I misunderstood the concept of Symbols?

Symbols are close to strings in Ruby, but they are not the equivalent to regular Java strings, although they, too, do share some commonalities such as immutability. But there is a slight difference - there is more than one way to obtain a reference to a Symbol (more on that later on).

In Ruby, it is entirely possible to convert the two back and forth. There is String#to_sym to convert a String into a Symbol and there is Symbol#to_s to convert a Symbol into a String. So what is the difference?

To quote the RDoc for Symbol:

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.

Symbols are unique identifiers. If the Ruby interpreter stumbles over let's say :mysymbol for the first time, here is what happens: Internally, the symbol gets stored in a table if it doesn't exist yet (much like the "symbol table" used by parsers; this happens using the C function rb_intern in CRuby/MRI), otherwise Ruby will look up the existing value in the table and use that. After the symbol gets created and stored in the table, from then on wherever you refer to the Symbol :mysymbol, you will get the same object, the one that was stored in that table.

Consider this piece of code:

sym1 = :mysymbol
sym2 = "mysymbol".to_sym

puts sym1.equal?(sym2) # => true, one and the same object

str1 = "Test"
str2 = "Test"

puts str1.equal?(str2) # => false, not the same object

to notice the difference. It illustrates the major difference between Java Strings and Ruby Symbols. If you want object equality for Strings in Java you will only achieve it if you compare exactly the same reference of that String, whereas in Ruby it's possible to get the reference to a Symbol in multiple ways as you saw in the example above.

The uniqueness of Symbols makes them perfect keys in hashes: the lookup performance is improved compared to regular Strings since you don't have to hash your key explicitly as it would be required by a String, you can simply use the Symbol's unique identifier for the lookup directly. By writing :somesymbol you tell Ruby to "give me that one thing that you stored under the identifier 'somesymbol'". So symbols are your first choice when you need to uniquely identify things as in:

  • hash keys
  • naming or referring to variable, method and constant names (e.g. obj.send :method_name )

But, as Jim Weirich points out in the article below, Symbols are not Strings, not even in the duck-typing sense. You can't concatenate them or retrieve their size or get substrings from them (unless you convert them to Strings first, that is). So the question when to use Strings is easy - as Jim puts it:

Use Strings whenever you need … umm … string-like behavior.

Some articles on the topic:

I'm looking for a book in the vein of Eloquent Ruby which, while not being targeted at the ruby beginner, gives a great overview of what 'grown up' idiomatic ruby code looks like, and gives great examples of how people might use the powers of the language. I found that the book almost perfectly mirrored what the experienced real world rubyists were writing.

I've settled quite comfortably now into obj-c, but I'd love to read a book like this that would take me from competent to enlightened. Are there any books/resources that might achieve this?

Take a look at this book: Programming in Objective-C I only have read some sections from it, but I think it mets your requirements, has a lot of helpful code and easy to follow tutorials and it's targeted to beginners and experienced programmers. As you can confirm in the book description:

The book makes no assumptions about prior experience with object-oriented programming languages or with the C language (which Objective-C is based upon). Because of this, both beginners and experienced programmers alike can use this book to quickly and effectively learn the fundamentals of Objective-C. Readers can also learn the concepts of object-oriented programming without having to first learn all of the intricacies of the underlying procedural language (C).

I spend a lot of time commuting. At the moment I spend this time listening to news podcasts. Recently I started listening to some educational books. I found some good books for other topics, like management and marketing, but I was wondering if there are any books for software developers/engineers or about computer science in general that can be listened to?

I immediately though of Eloquent Ruby but realised that code blocks and diagrams won't carry across well.

Do you know of any books, perhaps about thought or design patterns, that can be listened to?

It's been a long time since I asked this question but I realised that I have since been listening to a couple of podcasts that specifically address this.

Ruby Rogues - A weekly panel discussion about all aspects of Ruby covering design, gems, libraries and more meta subjects such as gender issues an contracting tips.

Javascript Jabber - Identical to Ruby Rogues but for Javascript

I have been trying to get into Ruby and the Rails framework for a while now, but somehow I find it quite hard to get started.

I have programming experience with Java, and web languages like PHP, JS. I've read around StackOverflow for a bit and while some recommend learning Ruby first, others recommend to get started with RoR straight away.

I would like to have a strong background of Ruby first before learning the framework. However, I'm not sure which are the right resources to start learning from.

Of course, there's the 'Pickaxe book', but while it's good and make things understandable, it seems to be giving code snippets more than anything else (I've only made it through the first three chapters, still going). Some of the Rails books I've read start up a project and guide you through (like the RoR tutorial book, the Agile RoR book,..). Are there any books out there for Ruby itself that have a similar approach, that is, instead of going over every part of the language, I'd like to build a project and thén go over the different parts of the language.

I would suggest Head First Rails. Its the best book I have ever read on Rails.

Also you can read this very good book Getting real on rails by the rails founder

To learn Ruby itself, I'd recommend Beginning Ruby by Peter Cooper. It covers the essentials of the language and tools with small practical projects. The chapter on Rails does use Rails 2, so it will give you the concepts but you shouldn't rely on the detail there.

Beyond that, I would suggest either Design Patterns in Ruby or the newly released Eloquent Ruby, both by Russ Olsen. The Design Patterns book is excellent at explaining the standard patterns and demonstrating a Ruby way to approach them. I haven't read Eloquent Ruby yet, but it is getting very positive reviews.

I have the following code for

h2.each {|k, v|
   @count += 1
   puts @count
   sq.each do |word|
       if Wordsdoc.find_by_docid(k).tf.include?(word)
       sum += Wordsdoc.find_by_docid(k).tf[word] * @s[word]
       end
     end
   rec_hash[k] = sum
   sum = 0
   }

h2 -> is a hash that contain ids of documents, the hash contains more than a 1000 of these Wordsdoc -> is a model/table in my database... sq -> is a hash that contain around 10 words

What i'm doing is i'm going through each of the document ids and then for each word in sq i look up in the Wordsdoc table if the word exists (Wordsdoc.find_by_docid(k).tf.include?(word) , here tf is a hash of {word => value}

and if it does I get the value of that word in Wordsdoc and multiple it with the value of the word in @s which is also a hash of {word = > value}

This seems to be running very slow. Tt processe one document per second. Is there a way to process this faster?

thanks really appreciate your help on this!

As you have a lot going on I'm just going to offer you up to things to check out.

  1. A book called Eloquent Ruby deals with Documents and iterating through documents to count the number of times a word was used. All his examples are about a Document system he was maintaining and so it could even tackle other problems for you.
  2. inject is a method that could speed up what you're looking to do for the sum part, maybe.
  3. Delayed Job the whole thing if you are doing this async-ly. meaning if this is a web app, you must be timing out if you're waiting a 1000 seconds for this job to complete before it shows it's answers on the screen.

Go get em.

I started learning ruby on rails about 3 month ago. I' ve follow several tutorial on twitter clone and i'm on my way to finish the Ruby on rails tutorial by micheal hartl and was wondering how do i make sure to push for the next level. My goal is to be able to make great app that can deal the actual web standard . There is a lot of content to learn rails for beginner but i would like to get blog, tutorial ,books or any other link for those how want to push there knowledge on the framework forward . Thank you .

I think that every body answer is important to that question so i' not gonna validate any answer .by respect for everybody . but thanks a lot and keep adding answer and feedback .

1] What is a good book/Resource for Java programmers coming to Ruby. There is a list of good books on other threads but is it recommended to read any particular for those familiar with Java ?

2] Is there a book/resource for creating extensible code in Ruby. Any Ruby design patterns ? Let me give some background. We have a bunch of "performance workload" [database oriented] shell scripts lying around. Its a pain to change or extend them, so we want to rewrite them in Ruby. I don't have any Ruby experience so I want to make sure that I don't end up creating un-extensible ruby scripts from the shell scripts !

Thanks!

P.S: This is not web development, that's why I did not mention Rails.

I am an RoR newbie. I have created a small application in ruby which has small functions to execute the code.

e.g.

 def abc(xyz)
    some code
 end

 def ghi(xyz)
    some code
 end

 def jkl(output)
    some code
 end

 xyz = abc[ARGV(0)]
 output = ghi(xyz)
 puts jkl(output)

Now, when I run this code in command prompt using ruby .rb, it executes nicely and returns the desired results. But when I try to create a class and add this whole code to it e.g.

 class Foo
     def abc(xyz)
    some code
 end

 def ghi(xyz)
    some code
 end

 def jkl(output)
    some code
 end

 xyz = abc[ARGV(0)]
 output = ghi(xyz)
 puts jkl(output)
 end

It generates the error like "undefined method 'abc' for Foo:Class (NoMethodError)"

All I want to ask is that how shall I add this code to a class so that it can become more pluggable and get the desired results.

Thanks in advance.

As this is written, these are all instance methods. You need to make them class methods like these two examples, or you could leave them as is and create an instance of the class. Either way, you should probably move the last three statements outside the class definition.

class Foo
  class << self
    def abc(xyz)
      some code
    end

    def ghi(xyz)
      some code
    end

    def jkl(output)
      some code
    end
  end
end
xyz = Foo.abc('something')
output = Foo.ghi(xyz)
puts Foo.jkl(output)

OR....

class Foo
  def self.abc(xyz)
    some code
  end

  def self.ghi(xyz)
    some code
  end

  def self.jkl(output)
    some code
  end
end
xyz = Foo.abc('something')
output = Foo.ghi(xyz)
puts Foo.jkl(output)

EDIT: To answer your question in the comments, this is how you would instantiate the class and call using instance methods.

class Foo
  def abc(xyz)
    some code
  end

  def ghi(xyz)
    some code
  end

  def jkl(output)
    some code
  end
end
bar = Foo.new
xyz = bar.abc('something')
output = bar.ghi(xyz)
puts bar.jkl(output)

If you don't have any Ruby learning materials yet, you might want to check out Chris Pine's tutorial, which includes a section on classes and how they work. As for books, here is a great book for Ruby in general and here is a question regarding books for Rails. I would suggest getting a decent grasp of Ruby before getting too deep into Rails.

I am trying to learn ROR these days and have basic knowledge of ruby, but often working with rails, I get to the point where it seems as if I don't know a bit about ruby.

Just to explain the point, in rails we use has_many keyword. I did not learn any such thing when I was going through ruby tutorials but just came to know that it has something to do with meta-programming in ruby (I have no idea what is meta programming).

So I would like to know if there is any book/tutorial which explain all the points/syntax/concepts of ruby, which a newbie would see while programming in rails.

Thanks to "Jonas Elfström", in simple words, what I am looking for is to know "how Rails uses Ruby"

Thanks.

has_many isn't a keyword, it's simply a class method in the ActiveRecord::Associations module.

It's documented here and you can even view the source if you scroll down a bit.

Associations are a set of macro-like class methods for tying objects together through foreign keys. They express relationships like “Project has one Project Manager” or “Project belongs to a Portfolio”. Each macro adds a number of methods to the class which are specialized according to the collection or association symbol and the options hash. It works much the same way as Ruby’s own attr* methods.

If you already know Ruby the Rails Guides could get you going but it might be easier to learn from one of the books listed at the documentation page or by watching a couple of screencasts.

For books about Ruby I've never seen such praise as what Eloquent Ruby gets.

I currently have a Ruby-based DSL for creating slides that uses instance eval:

# slides.rb
slide {
  title 'Ruby Programming'
  subtitle 'A simple introduction'
  bullet 'First bullet'
  bullet 'Second bullet'
}

# implementation:
class DSL
  class Slide
    def title(title)
      @title = title
    end
    # ...etc...
  end

  def slide(&block)
    @slides << Slide.new.instance_eval(&block)
  end
end

dsl = DSL.new
dsl.instance_eval(File.read('slides.rb'))

Which results in something like this:


Ruby Programming

A simple introduction

  • First bullet
  • Second bullet

I would like to take this to the next level by creating a DSL that does not use Ruby syntax. Maybe something more like YAML or Markdown:

title: Ruby Programming
subtitle: A simple introduction
* First bullet
* Second bullet

How can I create a DSL/parser for this type of syntax?

I believe Cucumber uses Ragel for its parser, here's a decent looking intro to it using Ruby...

Treetop is also pretty common, along with Parslet.

ANTLR, Rex and Racc... All kinds of ways to handle external DSLs.

Eloquent Ruby has a chapter on external DSL creation, from basic string parsing and regexes to using Treetop...

ok, i'm about at that point in my ruby career where this should be tripping me up.

I have a model called distribution.rb where I have the follwoing protected method:

  def update_email_sent_on_date
    if self.send_to_changed?
      self.date_email_delivered = DateTime.now
    end
  end

I then call this method from my controller:

 distribution.update_email_sent_on_date

however, I'm getting this error:

NoMethodError (protected method `update_email_sent_on_date' called for #<EmailDistribution:0x131a1be90>):

the distribution object is indeed an EmailDistribution (a subclass of distribution where the method is defined). I thought this would work. In any case, I also tried moving the method to the subclass EmailDistribution but no luck. Same error message.

I'd also like to step back and say that what I'm trying to do overall is store the timestamp of when another field in the distribution model is updated. If there's a simpler way, please enlighten me.

I think you're getting tripped up because you are using the protected declaration when you actually want the private declaration.

The protected term in ruby acts differently in other conventional languages.

In Ruby, private visibility is what protected was in Java. Private methods in Ruby are accessible from children. This is a sensible design, since in Java, when method was private, it rendered it useless for children classes: making it a rule, that all methods should be "protected" by default, and never private. However, you can't have truly private methods in Ruby; you can't completely hide a method.

The difference between protected and private is subtle. If a method is protected, it may be called by any instance of the defining class or its subclasses. If a method is private, it may be called only within the context of the calling object---it is never possible to access another object instance's private methods directly, even if the object is of the same class as the caller. For protected methods, they are accessible from objects of the same class (or children).

This is a slightly clearer explanation IMHO, from the book Eloquent Ruby by Russ Olsen:

Note that in Ruby, private methods are callable from subclasses. Think about it: You don't need an explicit object reference to call a superclass method from a subclass.

The rules for protected methods are looser and a bit more complex: Any instance of a class can call a protected method on any other instance of the class.

Lastly, it's good to note that in ruby you can always call private or protected methods regardless of whether they are accessible by using the send method. So if you were in a pinch and just needed to work you could just call it like this and then worry about the private/protected declarations later:

distribution.send(:update_email_sent_on_date)

Read this for more a better explanation..

I'm working with the Tumblr API right now and they have various types of posts (text, photo, video, quote, link, etc.). I'd like to make one parent class TumblrPost and then a bunch of sub-classes such as TumblrTextPost. If I do this, would there be a way to access each post via TumblrPost (ie. TumblrPost.all.each) regardless of sub-class? (NOTE: I'm using MongoDB and Mongoid)

Or should I maybe make each sub-class a module and then just do class TumblrPost include TumblrTextPost, etc.?

I'm not sure if you're talking about accessing each TumblrPost instance or each TumblrPost subclass.

If you want to access each instance, you can set up a class instance variable in TumblrPost and update with every new instance in the constructor:

class TumblrPost
  @all_instances = []

  class << self
    attr_accessor :all_instances
  end

  def initialize
    TumblrPost.all_instances << self
  end
end

TumblrTextPost = Class.new(TumblrPost)

t1 = TumblrPost.new
t2 = TumblrTextPost.new

puts TumblrPost.all_instances

If, on the other hand, you want to be able to iterate over each of the subclasses of TumblrPost, you can use the inherited hook to keep track of them.

class TumblrPost
  @all_subclasses = []

  class << self
    attr_accessor :all_subclasses
  end

  def self.inherited(subclass)
    @all_subclasses << subclass
  end
end

TumblrTextPost = Class.new(TumblrPost)
puts TumblrPost.all_subclasses

Source: Russ Olsen's Eloquent Ruby

I am looking for a good Ruby teaching guide (in pretty much any form) that gives a good sense of what is needed for programming with the Rails framework.

I took up Rails with the Agile Web Development with Rails 2nd Edition. I have their latest (4th) edition and recommend it, but there are lots of other resources out there now.

One in particular that I would very much recommend is the free Ruby on Rails Tutorial by Michael Hartl. It's up to date and teaches you how to use not only Ruby and Rails, but also other modern and important tools such as RVM for Ruby/gem management, Git for version control and RSpec for testing. It encourages a great test-driven workflow, so I'd recommend it even if you're not a beginner. I actually used this tutorial a few months back to refresh my memory and get into the new Rails 3 after having been out of it for over a year.

After you're comfortable with the Rails framework, then you should learn the Ruby language it is built upon. This is the stage I am at. Some of the books I'd recommend for learning Ruby are:

  • Eloquent Ruby - teaches you the Ruby way in many chapters covering a wide spectrum of the Ruby language. Great read for polishing and enforcing your Ruby knowledge, and also great to re-read just to reinforce everything!
  • The Ruby Programming Language - co-authored by the author of Ruby himself, Yukihiro Matsumoto...need I say more? This is quite in-depth so not great for beginning to learn the language but great for helping you to master it.
  • The Well Grounded Rubyist - currently going through this book. It is well written and covers a lot of ground, good for getting the hang of Ruby, but probably assumes you're not a programming newbie.

Obviously this is based on my experience and recommendations I have received from friends and colleagues, so I'm not saying this is the path for everyone interested in Ruby/Rails, but so far it's working for me. I'll be interested in seeing what resources others recommend here.