1. `String#split` without arguments does a good job of command input parsing

    I think this example pretty much speaks for itself:

    >> "    do   \t\n  some   stuff   ".split
    => ["do", "some", "stuff"]
    

    You don’t even need to strip your input.

     
  2. Strange `#`-comment behaviour in multiline `eval` blocks

    I do a lot of metaprogramming, which sometimes involves multiline eval blocks. Those blocks are actually part of the program, which are subject to debugging. As we all know, one of the most accessible debugging methods is commenting stuff out.

    There’s one little feature we should be aware of when using multiline eval blocks: the #-comment might not work as we expect it to.

    Consider this example:

    eval %{
      puts "Setting name"
      @name = "Joe"
    }
    

    Fairly primitive, should obviously work. Now let’s suppose that we want to temporarily comment out the @name = line.

    eval %{
      puts "Setting name"
      #@name = "Joe"
    }
    

    Looks quite regular, but now this stuff happens:

    SyntaxError: (eval):3: syntax error, unexpected '=', expecting $end
         = "Joe"
          ^
    

    First, the workaround. Use more than one # character or put a space bar between # and @name. Both should work:

    • ##@name = "Joe"
    • # @name = "Joe"

    Second, the explanation. Try this in IRB:

    >> @s = "xys"
    >> "#@s"
    => "xyz"
    

    Aha! Ruby interpreter (both 1.8 and 1.9, by the way) treats #@var as an interpolation token. So now we know why the original example crashed: we tried to comment out @name =, put a hash sign before it, but inadvertently turned it into an interpolation statement.

    Moral:

    • Ruby isn’t to blame.
    • eval isn’t to blame.
    • String interpolation isn’t to blame.
    • Just pay a little more attention to special chars sitting next to # in string values. :)
     
  3. `File.expand_path` doesn’t always produce a real (absolute) path

    File.expand_path is one of the most useful path manipulation methods I use in almost every Ruby file. If you also use it often, please keep in mind that it doesn’t always convert symlinks to real paths.

    >> File.expand_path("~/.irbrc")     (1)
    => "/home/alexrb/.irbrc"
    >> File.expand_path(".irbrc")       (2)
    => "/.devel/home/alexrb/.irbrc"
    

    My /home/alexrb is actually a symlink to /.devel/home/alexrb:

    >> ENV["HOME"]
    => "/home/alexrb"
    >> File.realpath ENV["HOME"]
    => "/.devel/home/alexrb"
    

    Note that example (2), based on current directory, did produce an absolute path, whereas (1) didn’t.

    Conclusion: If you want real path for sure, use File.realpath on top of File.expand_path.

     
  4. Filtering RSpec examples

    A single spec file may contain hundreds of examples. What if we want to stay focused on a particular one and skip the others for now? In other words, how do we filter?

    Up to this writing RSpec (2.11) supports the following ways to filter examples:

    • By line number in the spec file (-l).
    • By description string (-e).
    • By tag (-t).

    Filtering by line number:

    $ rspec some_spec.rb -l 159
    

    Filtering by description string:

    $ rspec spec/models/user_spec.rb -e "User is admin"
    

    Filtering by tag:

    it "should generally work", :focus do
      true.should == true
    end
    
    $ rspec some_spec.rb -t focus
    

    I’ve been using all three methods for quite a while now. Filtering by line number seems to be by far the most versatile and frequently used way. Does your experience differ from mine?

     
  5. Yield control back to `EventMachine`

    Suppose we’re listening to a message queue within an EventMachine scope. Suppose we’ve got a message, but it’s not the one we’re expecting, so we’d like to skip it hassle-free. How can we pass control back to EM without having to wrap everything in a long if?

    The short answer is: use next. Example follows.

    EventMachine.run do
      queue.subscribe do |message|
        if not message.match /known_to_us/
          puts "Unknown message, skipping (message:#{message.inspect})"
    
          # Yield control back to EventMachine.
          next
        end
    
        # Proceed with reply.
        ...
      end
    end
    
     
  6. It’s not possible to create a local variable via `eval`

    Consider this IRB snippet:

    >> eval("v = 1")
    >> v
    NameError: undefined local variable or method `v' for main:Object
    

    That’s Ruby 1.9.

    In Ruby 1.8 it was possible to create locals via eval, but that’s generally due to lack of proper optimization.

    Yakihiro explains the mechanics behind it.

    To keep it short: In Ruby 1.9 locals are created compile-time. eval is dynamic and has its own scope. If the local exists, eval will assign it. If not, it will stay private to eval’s scope.

     
  7. Aspects of `Marshal.dump`/`Marshal.load`

    Dumping and loading object data via Marshal is terribly efficient, but certain aspects of it are better be known.

    • Marshal.load doesn’t call initialize. In fact, an empty object is created and filled with data in a “procedural” way. The only way to gain control on Marshal.load is to define a marshal_load method in your class.

    • You cannot Marshal.dump the object if it has singleton (eigenclass) methods in it. The symptom is:

      TypeError: singleton can't be dumped
      

      This situation is pretty hard to debug since no other details are printed (Ruby 1.9.2).

    • Marshal.load does not autoload classes, even if you’re under Rails. It means that to load data cleanly you first need to “touch” all classes which may be contained in the dump. Otherwise you’re risking to get into something like:

      ArgumentError: undefined class/module MyKlass::
      

      The most reliable way to ensure all names loaded correctly is to do a require_dependency per each dependency in class hierarchies that are subject to dumping and loading. Example:

      # Marshal hacks.
      require_dependency "matcher/date"
      require_dependency "matcher/figure"
      require_dependency "matcher/url"
      
      module Parser
        class Sentence < ::Parser::Base
          def initialize
            @matcher = {
              :date => ::Matcher::Date.new,
              :figure => ::Matcher::Figure.new,
              :url => ::Matcher::Url.new,
            }
      
            ...
          end
      
          ...
        end
      end
      
     
  8. 03:33

    Tags: ruby

    Private singleton methods

    When creating singleton methods in classes and modules I prefer the def self.name notation since I think it’s more distinct, plus a few more reasons. The limitation of it is that it doesn’t allow to create private methods by default.

    module Mo
      private
    
      def self.private?
        "No!"
      end
    end
    
    >> Mo.private?
    => "No!"
    

    The solution is using class << self notation:

    module Mo
      class << self
        private
    
        def actually_private?
          "Oh yes... But you won't see this, I'm private you know..."
        end
      end
    end
    
    >> Mo.actually_private?
    NoMethodError: private method `actually_private?' called for Mo:Module
    
     
  9. RSpec pending (placeholder) examples

    A convenient way to declare RSpec tests without actually writing them now:

    it "should accept valid `site` only" do
      pending("TODO")
    end
    

    Pending examples are reported separately. Also, if colors are enabled, they are nicely decorated so you won’t miss them.