Archive for the “Ruby” Category


I finally found out how to do this, from the Rails Routing shortcut by David Black. In the Rails console, do this:

include ActionController::UrlWriter
default_url_options[:host] = 'whatever'

Then you can call your named route methods directly from the console.

Comments 1 Comment »

I am happy to report that AltLaw.org’s switch to Solr has worked very well. Solr is a RESTful search engine, built on Lucene. The setup was more complicated than just using a search library, but the rewards were worth it.

Before, I was using Ferret, which I still like. It’s a great library, and Dave Balmain has done incredible work producing a fast search engine that integrates well with Ruby. I still use it on other sites. But Solr was a better fit for AltLaw.

With Ferret, I was trying to shoe-horn large, unstructured documents into a system — ActiveRecord, MySQL, and acts_as_ferret — that is better suited to small, structured records. Now I use Solr as both a search engine and a document store, eliminating MySQL from the picture. That, combined with Solr’s built-in caching, has dramatically decreased the server load (from around 2.00 to under 0.30) while visibly improving search performance.

Also, I think it helps that Solr is not integrated with Ruby. The solr-ruby gem is not well documented, but easy to figure out, as it’s just a thin wrapper over the Solr APIs. Having the search engine in a separate process made it easier to separate the indexing & searching part of the code from the web application. As a result, the Rails code shrunk to one-fourth its former size.

Comments No Comments »

An interesting tidbit: can your programming language parse a < b < c? Perl can’t. Ruby can, but returns an error “undefined method `>’ for false:FalseClass.” Interestingly, Python accepts it, and even gives the correct result. Something clever must be going on in the parser to make that work.

Update October 17: Although Lisp can’t parse the expression directly, it does correctly handle the equivalent S-expression (< a b c).

Comments 2 Comments »

Answer: you’re using the latest version of Rails (1.2.3), which slightly changes the syntax of its SQL statements. cached_model relies on a regular expression to match that SQL statement.

To fix: Dive into the source of the cached_model gem, find the file lib/cached_model.rb, and change the first line after def self.find_by_sql to this:

    return super unless args.first =~ /^SELECT \* FROM #{table_name} WHERE \(#{table_name}\.`?#{primary_key}`? = '?(\d+)'?\) *(?:LIMIT 1)?/

And it works!

Comments No Comments »

Wowsers. I just spent two nail-biting, hair-pulling days getting Ruby on Rails running on a new dedicated server. What’s the deal here? I spent the first six hours trying to get Capistrano to work with darcs. Then I gave up on Capistrano.

I didn’t know anything about Mongrel, nginx, Lighttpd, or any of that stuff, so I decided to try the simplest setup I could think of: Apache2 with FastCGI. I’d done this on a shared host before, so at least I had some vague idea of what to expect. Some things I learned:

  • Do not use Ubuntu’s rubygems package; build from source. The Ubuntu package has a weird configuration that stores gems under /var, where nothing can find them.
  • Do not use Ubuntu’s fcgi-ruby package. Install the gem (see below).
  • Make sure your web-data user (or whatever user Apache runs as) has write privileges on RAILS_ROOT/log, RAILS_ROOT/tmp, RAILS_ROOT/index (if you’re using Ferret), and RAILS_ROOT/public (if you’re using page caching).
  • Make sure there are no leftover files owned by other users in any of those aforementioned directories.
  • Don’t rely on Apache to provide Rails with environment variables like RAILS_ENV and PATH. Set them in environment.rb.

My conclusion, after I finally got the app running: Rails has major work to do when it comes to startup error reporting. When dispatch.fcgi dies repeatedly without neither output nor log messages, there’s something wrong. Seriously, how hard could it be to dump a plain-text HTTP response with a stack trace? That way I’d at least know why it won’t start, instead of staring at “Rails application failed to start properly” for hours on end.

For the record, here was the installation recipe I came up with. This is on Ubuntu Feisty:

MySQL:
sudo aptitude install mysql-server mysql-client

Memcached:
sudo aptitude install memcached

Basic ruby essentials:
sudo aptitude install ruby libruby1.8-extras irb rdoc ri

Extra ruby libraries:
sudo aptitude install libreadline-ruby libopenssl-ruby libmysql-ruby

Essentials for building native ruby extensions:
sudo aptitude install build-essential ruby1.8-dev libfcgi-dev

The latest version of rubygems (NOT the Ubuntu package):

wget http://rubyforge.org/frs/download.php/20989/rubygems-0.9.4.tgz
tar -xzf rubygems-0.9.4.tgz
cd rubygems-0.9.4
sudo ruby setup.rb

Gems:
sudo gem install --include-dependencies --no-rdoc --no-ri rake rails acts_as_ferret acts_as_taggable asciify BlueCloth builder cached_model chronic feedtools ferret hpricot memcache-client mongrel RedCloth fcgi

Comments No Comments »

I’m certainly not the first to do this, but I felt like writing it. Comparing Ruby and Common Lisp:

Syntax: Advantage, Common Lisp. No contest here. Ruby’s syntax is ugly, with all those ends hanging around and the { |var| ... } block syntax. The one thing Ruby has going for it is conciseness. The block syntax, ugly though it may be, is shorter than (lambda (var) ...), which may explain why Ruby uses blocks everywhere while CL programmers go out of their way to avoid lambdas.

Libraries: Advantage, Ruby. CL has some really interesting high-level libraries, but it’s lacking in bread-and-butter utilities like date/time, file handling, and string munging.

Speed: Everybody knows Ruby is slow. CL with native compilation is not. On the other hand, a lot of Ruby libraries are written in hand-optimized C, so they’re plenty fast. But just try to decipher that C code when you want to modify the behavior of a library. Slight advantage, CL.

Resource usage: Slight advantage, Ruby. Most CL implementations carry the baggage of a 20MB runtime. Ruby by itself is small, but some major libraries (e.g. Rails) are memory hogs.

Web development: Advantage, Ruby. Rails rocks. The CL web frameworks are complex and not well tested in mainstream production use.

Testing: Dead heat. Both languages have several excellent testing frameworks. There’s been some particularly innovative work on Behavior-Driven Development in Ruby with rSpec.

Metaprogramming: Advantage, CL. Although Ruby is famous for its metaprogramming abilities, it can’t compete with CL’s macro system and the Meta-Object Protocol. I find the Ruby metaprogramming methods confusing, so I fall back on evaluating template strings, which is error-prone.

Difficulty: Ruby is definitely easier to learn, especially for someone with some C/Perl background. Common Lisp is really different, and shows its age in areas like file handling.

Code organization: This can’t be quantified, but I find it easier to structure my code in Ruby. Knowing at the outset that everything will go into classes and methods makes it more obvious how code is divided up. Lisp code, the “big ball of mud” as some call it, grows more organically but leaves me with a disorganized mess of individual functions scattered across a bunch of source files. I think writing well-organized code in Common Lisp requires more discipline and attention to detail than it does in a class-oriented language like Ruby.

Conclusion: Both languages have their problems. I feel more affection for Common Lisp, and I’m glad I learned it, but Ruby will probably continue to be my primary working language for a while. If I were starting something really unique that I would have to build from the ground up, Lisp would be my choice. But for building dynamic web sites, Ruby gets the job done right now. I hope Ruby will continue to evolve in a Lispy direction, with an abstract syntax tree and a macro system. Throw in an optimizing compiler and it might almost be perfect.

Comments 2 Comments »

When I first discovered dynamically-typed languages like Perl and Ruby, I was convinced of their superiority to statically-typed languages like C++. No longer did I have to waste hours typing redundant type declarations or adding casts just to make the compiler happy. Dynamic typing allowed me to work quickly and unencumbered in what felt like a natural manner.

Lately, however, I’ve been experiencing some of the drawbacks. Many times I have started a long batch process running in Ruby, only to come back hours later to find that it crashed before getting halfway through because I made a mistake. Often, the mistakes were simple typos or misspellings. Sometimes they were the result of sloppy code, like not checking if a returned value is nil.

Because my code isn’t error-checked before it runs — in Rails, some code doesn’t even get syntax-checked before it runs, thanks to lazy autoloading — my mistakes don’t manifest until hours or days into a process. Then I have to fix them and start the process over.

Now I realize while statically-typed and -checked languages were so important in the pre-PC era. If you had a turnaround time of several hours between submitting your program for execution and receiving the results, you would want to be certain that it would work correctly. The instant feedback of the write-compile-run (or, with an interpreted language, just write-run) cycle makes it easier to be sloppy.

A static compiler or syntax checker would probably catch most of the mistakes I just described. So would proper unit tests. But the ability to constantly restructure large sections of code as I explore the problem — an ability granted by an interpreted, dynamic language — also makes it hard to keep tests up-to-date. Writing tests comes to seem as tedious and unhelpful as type declarations.

What I really want is a “magic” compiler that can look through my code and point out all the mistakes. A combination of good unit tests and a test coverage tool would come close, but that requires a lot of extra effort on my part.

Comments 2 Comments »

I’ve been dredging up my C++ for a class recently, and I’m struck by just how weird it feels now that I spend most of my time with Ruby.

I was all proud of myself for remembering how to write a copy constructor. Then I ran into a situation like this:

MyClass a = foo;
MyClass c;
c = foo;

The first line was fine; the last segfaulted. What the heck?

I had hit upon the subtle difference between assignment at construction time and normal assignment. The former calls the copy constructor, the latter calls operator=.

MyClass a = foo;  // calls copy constructor MyClass(foo)
MyClass c;
c = foo;  // calls operator=

I had neglected to provide an operator= for MyClass, so the compiler invented one for me. Since MyClass contained pointers to other structures, that naturally led to problems pretty quickly.

Had I not known to look up the specific behavior of operator=, and then implement a correct one for MyClass, I would have been really confused. This sort of subtlety is what makes me think of C++ as a “hard” language and Ruby as an “easy” language.

To be sure, Ruby has its subtle quirks too, but they occur less frequently and usually around “advanced” topics like metaprogramming. In C++, even a fundamental operation like assignment can have strange, unpredictable properties.

Comments 1 Comment »

I don’t much like programming language tutorials. They’re useful for getting the general sense of what a language is all about, but they inevitably elide too many crucial details to teach you how to write a real program.

When I got interested in Ruby, I read the on-line version of Programming Ruby: The Pragmatic Programmer’s Guide and floated in a confused, dreamlike state through Why’s (Poignant) Guide to Ruby.

I didn’t feel like either one gave me a complete grasp of the language, though. I started digging into the standard library documentation — my usual second stop when learning a new language — but found it pretty brief and confusing for a newcomer to Ruby.

Then I picked up a copy of The Ruby Cookbook. This was the perfect programming book for someone who likes to dive right in and start writing programs. It’s not just about Ruby the language, nor is it a tour of the standard library. Rather, it’s a comprehensive list of everyday programming tasks — ranging from “Building a string from parts” to “Managing Windows services” — with solutions for how to do them in Ruby. Each solution is followed by a discussion of the whys and wherefores, the language features or external libraries involved. Reading the discussions gives insight into how Ruby works and why it works the way it does.

The Ruby Cookbook was an enjoyable way to learn Ruby, which I now use for the majority of my work. It’s even got some geek humor embedded in its code examples, like this one on string templates:

template = 'Oceania has always been at war with %s.'
template % 'Eurasia'
#  =>  "Oceania has always been at war with Eurasia."
template % 'Eastasia'
#  =>  "Oceania has always been at war with Eastasia."

Not long after reading the book, I got to know one of the authors, Leonard Richardson, and his wife Sumana. Nice people, and Leonard’s a good cook of the non-Ruby variety as well.

I’ll end with my favorite code example in the book, in a section about the IMAP email client library:

From: jabba@thehuttfoundation.org
Subject: Bwah!
---
From: jabba@thehuttfoundation.org
Subject: Go to do wa IMAP

Comments No Comments »

I was at LispNYC last night listening to Anton van Straaten discuss his work on R6RS, the new Scheme standard. One surprising change from R5RS is that eval is defined in a library.

Eval, in a library? Holy scopes! The Common Lispers in the audience were aghast. Even the Schemers were a tad confused. Anton explained. The goal of Scheme, he said, has always been to incorporate as much dynamic behavior as possible without sacrificing efficient compilation. Towards this end, the R6RS eval is more limited than Common Lisp’s eval.

As I understand it, eval was central to McCarthy’s original design for LISP. Eval is LISP, and LISP is eval. Of course, as others reminded me later, LISP’s definition of eval with dynamic scope led to the 30-year “funarg” bug. Eval is also a thorn in the side of anyone trying to generate a standalone Common Lisp program — the possibility of a call to eval means the compiler has to include the entire Common Lisp runtime (up to 20 MB, depending on the implementation) in the final executable.

This got me thinking about Ruby, too. While Common Lisp and Scheme actually discourage the use of eval, Ruby is pretty casual about it. In a purely interpreted, dynamic language, that’s not a problem. But it would make it tough to implement a static Ruby compiler.

Comments 1 Comment »