Source: http://www.rubyinside.com/how-to-install-a-ruby-18-stack-on-ubuntu-810-from-scratch-1566.html

Want to install Ruby, RubyGems, and a collection of common gems on Ubuntu 8.10 (Intrepid Ibex) in just a few minutes? Here’s the skinny.

If you want, you could use something like Passenger-Stack to do the legwork for you, but I prefer doing manual installations so I know the full score. There are several “how to install Ruby on Ubuntu Intrepid” guides out there but none of them got it totally right for me. I’ve just used these instructions twice in a row so I know they work. Another bonus is you get ImageMagick and rmagick installed which some people get really frustrated with..

Note: These instructions assume you’re running as root for convenience. You can alternatively sudo every line or just run sudo bash until you’re done.

Install the system level basics

apt-get update
apt-get -y install build-essential zlib1g zlib1g-dev libxml2 libxml2-dev libxslt-dev sqlite3 libsqlite3-dev locate git-core
apt-get -y install curl wget

Install ImageMagick (for rmagick)

apt-get -y install libmagick9-dev

Install Ruby 1.8 (MRI)

apt-get -y install ruby1.8-dev ruby1.8 ri1.8 rdoc1.8 irb1.8 libreadline-ruby1.8 libruby1.8 libopenssl-ruby
ln -s /usr/bin/ruby1.8 /usr/bin/ruby
ln -s /usr/bin/rdoc1.8 /usr/bin/rdoc
ln -s /usr/bin/irb1.8 /usr/bin/irb
ln -s /usr/bin/ri1.8 /usr/bin/ri

Note: Some advise not to use the packaged version of Ruby on Ubuntu due to its performance. I’m not worried about this. If you are, replace this section with a download of the Ruby source code (http://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p72.tar.gz) and untar, ./configure, make and make install it by hand. You’re on your own with that though.

Install RubyGems (from source)

curl http://de.mirror.rubyforge.org/rubygems/rubygems-1.3.1.tgz | tar -xzv
cd rubygems-1.3.1 && ruby setup.rb install
cd .. && rm -rf rubygems-1.3.1
ln -s /usr/bin/gem1.8 /usr/local/bin/gem
gem sources -a http://gems.github.com # add Github as a gem source, you won't regret it

Install a set of starter Ruby gems

gem install rake nokogiri hpricot builder cheat daemons json uuid rmagick sqlite3-ruby fastthread rack

What next?

By this point you now have Ruby installed with RubyGems, a collection of gems (including rmagick) and you can branch off where you want. If you want to develop a Sinatra app, install the sinatra gem and you’re away. If you want to install Rails, gem install rails. And so forth.

If you want to install Apache with Passenger for hosting your apps, however, read on..

Optional: Install Apache and Passenger

echo "deb http://apt.brightbox.net hardy main" > /etc/apt/sources.list.d/brightbox.list
wget -q -O - http://apt.brightbox.net/release.asc | apt-key add -
apt-get update
apt-get -y install libapache2-mod-passenger

Note: Brightbox’s Passenger package is officially for Ubuntu 8.04 (Hardy) but it works fine on Intrepid in my experience.

If you need PHP5 as well:

apt-get -y install php5 libapache2-mod-php5 php5-mysql
/etc/init.d/apache2 restart

Optional: Need a very, very basic firewall?

apt-get -y install ufw
ufw allow to 0.0.0.0/0 port 80
ufw allow to 0.0.0.0/0 port 22 # (or whichever port you use for ssh)
ufw allow to 0.0.0.0/0 port 25 # (if you need mail in)
ufw enable

Note: You’re installing the firewall, not me, so don’t complain if you get locked out because of the firewall or something :) Ensure you have the correct ports and/or a console access to your server just in case (such as Linode supplies).

Source: http://railstips.org/2009/2/21/shoulda-looked-at-it-sooner

Just a little bit ago I twittered:

I’ve been using shoulda with rspec for past week. Now trying it on fresh rails project and liking it ok thus far.

To which Brandon Keepers replied with:

@jnunemaker what do you like about it?

I started to send a tweet back and realized it would make an ok post here.

History

I remember asking Brandon at RailsConf last year why he liked RSpec so much (I was using test/spec at the time) and his answer was, “I don’t know, just because.”

Of course after that response, he laughed and tried to explain. One thing I’ve noticed is that it is sometimes hard to explain why you prefer a certain tool over another. That said, I am going to give it a shot.

Shoulda with RSpec

When Joe Ferris announced that shoulda macros could now be used with RSpec, I switched away from rspec-on-rails-matchers pretty quickly. I’ve been using shoulda’s macros with RSpec for about a little while and today when I started a new side project, because of my little bit of familiarity and interest due to using it the past while, I thought what the heck, and went all or nothing with shoulda.

Toe Dipping

What is funny, is that I was completely anti-shoulda until they announced RSpec compatibility. I remember thinking, oh great, here comes another stupid testing framework. I looked it over several times and couldn’t find enough coolness to interest me in switching. When they announced that I could dip my toe in while still using RSpec, I gave it a shot. Honestly, without the toe dipping, it would have been a long time, if ever, before I even gave shoulda a fair shot.

The dipping of the toe method reminds me of git-svn. My first git experience was working with an svn repository. The same thing happened. I figured I had nothing to lose by dipping my toe in and a few hours later, I was hooked.

At first, as usual with new things, I was frustrated, followed by excited, followed by frustrated. After an hour or two of adding tests to the project, with the shoulda source code right by my side, things started to kind of click.

My Two Favorite Shoulda Things

1. As I look at my tests from various projects using test/unit, test/spec, rspec and this new project with shoulda, the shoulda tests just seem more readable. I don’t know if it is the context/should verbiage that I like better than describe/it or what, but my test files seem easier to scan and aesthetically more pretty (if that makes sense).

2. I love the shoulda controller macros. They put the few matchers that I created and used with RSpec to shame. That is not RSpec’s fault, I just love shoulda’s. I’m usually most interested in code and syntax, so here is a sample from the project I’m playing with that tests a basic sessions controller.

class SessionsControllerTest < ActionController::TestCase
  context "on GET to :new" do
    setup { get :new }

    should_render_a_form
    should_respond_with :success
    should_render_template :new
  end

  context "on POST to :create with valid credentials" do
    setup do
      User.stub!(:authenticate, :return => users(:jnunemaker))
      post :create, :username => 'jnunemaker', :password => 'secret'
    end

    should_return_from_session :user_id, "users(:jnunemaker).id" 
    should_redirect_to 'root_url'
    should_filter_params :username, :password
  end

  context "on POST to :create with invalid credentials" do
    setup do
      User.stub!(:authenticate, :return => nil)
      post :create, :username => 'jnunemaker', :password => 'fake'
    end

    should_respond_with :success
    should_render_template :new
    should_set_the_flash_to /Could not authenticate/
  end

  logged_in_as :jnunemaker do
    context "on DELETE to :destroy" do
      setup { delete :destroy }

      should 'log user out' do
        session[:user_id].should be(nil)
      end

      should_redirect_to 'login_url'
    end
  end
end

Note: I’m also using Jeremy McAnally’s stump for stubbing the User#authenticate method which makes an external web service call, his matchy library for the fancy session[:user_id].should assertion, and a macro I stole (logged_in_as) to easily setup authentication for controller tests. Nothing fancy, but I just like the way it flows.

Simple Model Test

If you are in the mood for more code, here are some of the tests from my user model. Yes, I’m making a twitter client. I’m dissatisfied with pretty much all the twitter clients out there (and I’ve used them all) so I decided to whip one together. I’ll probably open source it at some point.

class UserTest < ActiveSupport::TestCase
  should_have_many :user_statuses
  should_have_many :statuses, :through => :user_statuses

  context "#sync_with_twitter" do    
    should "not assign ignored attributes" do
      tweeter = new_tweeter(:id => '1234', :name => 'Shaq', :screen_name => 'THE_REAL_SHAQ', :created_at => '2006-08-13 22:56:06')
      User.sync_with_twitter(tweeter, 'secret')

      user = User.find_by_twitter_id('1234')
      user.created_at.should_not == user.twitter_created_at
    end

    should "create non-existant user" do
      assert_difference 'User.count' do
        tweeter = new_tweeter(:id => '1234', :name => 'Shaq', :screen_name => 'THE_REAL_SHAQ')
        User.sync_with_twitter(tweeter, 'secret')
      end
    end

    should "update existing user" do
      user = users(:jnunemaker)
      tweeter = new_tweeter(:id => user.twitter_id, :name => 'New Name')

      assert_no_difference 'User.count' do
        User.sync_with_twitter(tweeter, 'secret')
      end

      user.reload
      user.name.should == 'New Name'
    end
  end

  def new_tweeter(attrs)
    tweeter = Twitter::User.new
    attrs.each { |k,v| tweeter.send("#{k}=", v) }
    tweeter
  end
end

Again, I’m using Jeremy’s matchy (mentioned above) to get the .should == syntax. I still enjoy RSpec, but I’m pretty impressed with Shoulda. It feels very scannable/readable and the macros are really handy, both for testing models and controllers.

Oh, and for those who are wondering, all I did to set things up is install the gems and add the following to my config/environments/test.rb file.

config.gem 'thoughtbot-shoulda', :lib => 'shoulda', :source => 'http://gems.github.com'
config.gem 'jeremymcanally-stump', :lib => 'stump', :source => 'http://gems.github.com'
config.gem 'jeremymcanally-matchy', :lib => 'matchy', :source => 'http://gems.github.com'

Shoulda thoughts and reactions? Maybe the shoulda users out there could chime in with what they like best. I am also curious what is holding back others who haven’t tried shoulda out yet.

Source: http://www.rubyinside.com/passenger-stack-quickly-install-a-full-ruby-and-passenger-stack-1533.html

stack.png

Passenger-Stack is a set of scripts for the provisioning tool Sprinkle that make installing a full Ruby, Apache and Passenger-based stack almost a one-line task. It’ll take almost any UNIX-y server of your choice from a generic install through to deploying Rack-based apps (including those built with Rails, Merb, Sinatra, and Ramaze).

The Sprinkle scripts behind Passenger-Stack were developed by Ben Schwarz and the best introduction is his five minute screencast showing how it works (on Ubuntu 8.10 hosted with Slicehost). Ben is very keen for people to fork the scripts on Github and customize them further.

If you’re not familiar with Sprinkle, by the way, it’s a “software provisioning tool” that you can use to perform installs and remote builds with. In essence, it allows you to write installation scripts using a Ruby-based DSL.

Source: http://railstips.org/2008/6/10/programmers-should-give-up-more-often

You know that feeling? The one where you are in the zone. Every keystroke is intentional and the sound of them in succession sounds almost like music. Your chair feels comfy and your desk is clean, or at least mostly clean. The code you are producing could be framed and put on a wall and even your mom would admire its beauty. You’ve had that feeling right?

Contrast what I just presented, with that other feeling. You know it. I know you know it. You have a slight buzz in the front of your brain. Typos begin to abound and you are starting to think your fingers went drinking without you. You shift to and fro but your chair continues to feel like a block of wood. Your code is so convoluted that you sometimes don’t understand what you just wrote 30 minutes ago. In fact, the thing that should “just work” isn’t working and hasn’t been for the past 45 minutes.

What To Do?

So what are you to do? Push through you say! Mush, mush! I know in an hour I’ll once again feel fresh and write code that sounds like a harp from the Heavens. I’ve already spent 45 minutes, what’s another 15. Besides, I’m so close. FAIL! I have news for you Walter Cronkite, you won’t. Your code will begin to feel more and more like the spaghetti [insert previous language here] you use to write. You’ll get more uncomfortable, and most likely the buzz in your head will last for hours after you stop, quite possibly ruining the rest of your night.

Great Programming Requires Inspiration

I believe the ability to give up and to know when to give up is what sets great programmers apart from good, average and poor ones. Programming is art. Art is created through inspiration. Anyone can push through and churn out crappy code. The question is, are you self-aware to the point that you know when it’s time to stop?

Do Something Else

Next time you feel the buzz creeping into the front of your skull and your undies start riding up, stop! As the wait staff at Logan’s Roadhouse says, “Stop what you’re doin and swallow what you’re chewin.” Pet your cat. Read a few chapters from a book. Complete the next mission on Grand Theft Auto. Don’t push through. Do something other than programming that inspires you and I guarantee the inspiration for what you were working on will return.

What I Do

So what do I do when I hit the wall? I’ve never been much of a reader but lately I’ve turned to books. I’m not a fan of fiction, but I have discovered an ardent interest in business, especially now that I’m a business owner. Books like Good to Great, The Fred Factor, 4 Hour Work Week and Blink are inspiring me to think differently and write better code.

Source: http://railstips.org/2008/12/1/unless-the-abused-ruby-conditional

Some people hate unless in Ruby. I personally do not, but I try to abide by a few rules. I’ll explain with some examples below. The uses that I label as “ok” below could just be personal preference, so I will not refer to them as “good”, but I would definitely avoid using the ones I label as “bad”.

Statement Modifier…Ok

I think unless actually reads better than if ! when used as a statement modifier. For example, I think this…

raise InvalidFormat unless AllowedFormats.include?(format)

…reads better than this…

raise InvalidFormat if !AllowedFormats.include?(format)

I think the reason I like the former incarnation is because it would read like a sentence to almost anyone, even those unfamiliar with Ruby (like my mom and we all know it is important for moms to be able to read code).

Without Else…Ok

I also don’t mind using unless when you are just checking one condition and not using else like so…

unless foo?
  # bar that thing
end

With an Else…Bad

What I dislike is when unless is used with an else like so…

unless foo?
  # bar that thing
else
  # foo that thing
end

If you have code like this, just swap the code doing the work and use if. Trust me, it reads a lot better.

if foo?
  # foo that thing
else
  # bar that thing
end

The if version just feels easier to process than the version with unless. I think using unless with else is like speaking with double negatives. It slows down the next programmer in the code, as they have to think instead of just flowing through the conditional, if that makes sense.

When testing nil?…Bad

As Ryan Bates pointed out in the comments below, testing nil like this…

unless foo.nil?
  # do some foo
end

…is a bit more readable like this…

if foo
  # do some foo
end

unless foo.nil? and if foo equate to the same thing but is kind of a double negative issue, like I just mentioned about using unless with else. Thanks for the another bad unless tip Ryan!

With Multiple Conditions…Bad

The reason I hate (and it is hate, not just dislike as above) unless with multiple conditions is that I always forget whether the “not” applies to only the first conditional or to all of them. If you are wondering, the “not” does apply to all conditionals, but just talking about it has me feeling confused again, so please do not do this…

unless foo? && baz?
  # bar that thing
end

Instead, I would probably do something like this…

if !foo? || !baz?
  # bar that thing
end

Final Thoughts

unless is ok but do not throw it in your code willy nilly. I said “nil” get it? Hehe. Some might say that if unless can be so easily abused, why not avoid using it all. I guess I disagree with that, as I think it does actually improve code readability in some cases, as I mentioned above. Feel free to argue below and I will ignore you. :)

Source: http://www.rubyinside.com/how-you-can-help-the-state-of-deploying-ruby-webapps-in-the-next-5-minutes-1516.html

passengerlogo.pngCan you remember what a hideous chore it was to deploy Ruby-based apps (Rails apps being a key example) before early 2008? FastCGI, proxying schemes, plain old CGI – it was all a bit of a mess. It was so bad, in fact, that in January 2008 we posted No True “mod_ruby” Is Damaging Ruby’s Viability On The Web and kicked off a major discussion about it (115 comments!)

A couple of months later, an as-then unknown Dutch company called Phusion (headed by Ninh Bui and Hongli Lai) released mod_rails (a.k.a. Passenger), an Apache module that automatically handles server processes for Ruby apps and makes it a snap (just upload and touch a file) to deploy any Rack-based Ruby webapp with Apache – everyone has benefitted, including Sinatra, Merb and Ramaze development.

Phusion is now looking for help. They’re a company but they essentially give away their two main products: Passenger and Ruby Enterprise Edition. You can pay for an “enterprise license” but it’s really just a donation system. Now they’re looking to specifically raise $14,000 to get the next version of Passenger out of the door. They’re promising a lot – extended documentation, improved support and security, finalized Ruby 1.9 support, and, heck, too much to count.

Click here to lend your support to: Phusion Passenger first community sponsorship and make a donation at www.pledgie.com !

They have just $8,336 to go and if you want to help push forward the state of deploying Ruby-powered webapps, click here to donate (or read more about what they’re achieving). All donors will be credited.

P.S. In May 2008, we ran 28 mod_rails / Passenger Resources to Help You Deploy Rails Applications Faster that you might like to revisit.

P.P.S. Update: Ruddy ‘eck – it’s only 24 hours on and it’s down to just $2854.70 to go.. nice one guys!

Source: http://www.rubyinside.com/sprockets-a-ruby-powered-javascript-dependency-library-from-37signals-1520.html

Managing and organizing multiple JavaScript files in your Rails applications can be a real pain, especially when it comes to deploying your application and you need to minimize those JavaScript files down for better application performance.

Enter Sprockets, the new dependency management and concatenation library from 37signals (or, more specifically, Sam Stephenson). Once installed, Sprockets allows you to organize your application’s JavaScript files into smaller more manageable chunks that can be distributed over a number of directories and files.

Using directives at the start of each JavaScript file, Sprockets can determines which files your current JavaScript file depends on. When it comes to deploying your application, Sprockets then uses these directives to turn your multiple JavaScript files into a single file for better performance.

Sprockets also allows you bundle assets with your JavaScript, as well as allowing you to insert string constants in your JavaScript files, using a YAML file.

Sprockets is available as a Ruby gem or as a Rails plugin. The Sprockets source code is also available on GitHub.

Tha thứ mãi mãi

Tháng Hai 18, 2009

Lisa ngồi trên sàn với chiếc hộp trước mặt. Cái hộp cũ kĩ đựng 1 tờ giấy kẻ ô vuông. Và đây là câu chuyện đằng sau những ô vuông…

– Các con phải tha thứ cho anh chị em mình bao nhiêu lần… – Cô giáo trường Chủ Nhật đọc to luôn câu trả lời cho cả lớp nghe: “70 nhân 7 lần! ”

Lisa kéo tay Brent – em trai cô:

– Thế là bao nhiêu lần…

Brent viết số 490 lên góc vở Lisa. Brent nhỏ bé, vai hẹp, tay ngắn, đeo cặp kính quá khổ và tóc rồi bù. Nhưng năng khiếu âm nhạc của cậu làm bạn bè ai cũng phục. Câụ học pianô từ năm lên 4, kèn darinet năm lên 7 và giờ đây cậu đang chinh phục cây đèn Oboa. Lisa chỉ giỏi hơn em trai mình mỗi 1 thứ: bóng rổ, 2 chị em thường chơi bóng rổ sau giờ học. Brent thấp bé lại yếu, nhưng nó không nỡ từ chối vì đó là thú vui duy nhất của Lisa giữa những bảng điểm chỉ toàn yếu với kém của cô.

Sau giờ học, 2 chị em lại chạy ra sàn bóng rổ. Khi Lisa tấn công, Brent bị khuỷu tay Lisa huých vào cằm. Lisa dễ dàng ghi điểm. Cô hả hê với bàn thắng cho đến khi nhìn thấy Brent ôm cằm.

– Em ổn cả chứ… Chị lỡ tay thôi mà!

– Không sao, em tha lỗi cho chị – Cậu bé cười – Phải tha thứ 490 lần và lần này là 1, vậy chỉ còn 489 lần nữa thôi nhé!

Lisa cười. Nếu nhớ đến những gì Lisa đã làm với Brent thì hẳn 490 lần đã hết từ lâu lắm.

Hôm sau, 2 chị em chơi bắn tàu trên giấy. Sợ thua, Lisa nhìn trộm giấy của Brent và dễ dàng “chiến thắng”.

– Chị ăn gian! – Brent nhìn Lisa nghi ngờ.

Lisa đỏ mặt:

– Chị xin lỗi!

– Được rồi, em tha lỗi – Brent cười khẽ – Thế là chỉ còn 488 lần thôi, phải không…

Sự độ lượng của Brent làm Lisa cảm động. Tối đó, Lisa kẻ 1 biểu đồ với 490 hình vuông:

– Chúng ta dùng cái này để theo dõi những lần chị sai và em tha lỗi. Mỗi lần như vậy, chị sẽ gạch chéo 1 ô – Miệng nói, tay Lisa đánh dấu 2 ô. Rồi cô bé dán tờ biểu đồ lên tường.

Lisa có rất nhiều cơ hội đánh dấu vào biểu đồ. Mỗi khi nhận ra mình sai, Lisa xin lỗi rất chân thành. Và cứ thế… Ô thứ 211: Lisa giấu sách Tiếng Anh của Brent và cậu bé bị điểm 0. Ô thứ 394: Lisa làm mất chìa khoá phòng Brent… Ô thứ 417: Lisa dùng thuốc tẩy quá nhiều làm hỏng áo Brent… Ô thứ 489: Lisa mượn xe đạp của Brent và đâm vào gốc cây. Ô 490: Lisa làm vỡ chiếc cốc hình quả dưa mà Brent rất thích.

– Thế là hết – Lisa tuyên bố – Chị sẽ không có lỗi gì với em nữa đâu.

Brent chỉ cười: “Phải, phải”

Nhưng rồi vẫn có lần thứ 491. Lúc đó Brent là sinh viên trường nhạc và cậu được cử đi biểu diễn tại đại nhạc hội New York. Một niềm mơ ước thành hiện thực.

Người ta gọi điện đến thông báo lịch biểu diễn nhưng Brent không có nhà, Lisa nghe điện: ” Hai giờ chiều ngày mùng 10 nhé! ” Lisa nghĩ mình có thể nhớ được nên cô đã không ghi lại.

– Brent này, khi nào con biểu diễn… – Mẹ hỏi.

– Con không biết, họ chưa gọi điện báo ạ! Brent trả lời.

Lisa lặng người, mãi mới lắp bắp:

– Ôi!… Hôm nay ngày mấy rồi ạ…

– 12, có chuyện gì thế…

Lisa, bưng mặt khóc nức lên:

– Biểu diễn… 2 giờ… mùng 10… người ta gọi điện… tuần trước…

Brent ngồi yên, vẻ mặt nghi ngờ, không dám tin vào nhữnng gì Lisa nói.

– Có nghĩa là… buổi biểu diễn đã qua rồi……… – Brent hỏi.

Lisa gật đầu. Brent ra khỏi phòng, không nói thêm lời nào. Lisa về phòng, ngậm ngùi khóc. Cô đã huỷ hoại giấc mơ của em cô, làm cả gia đình thất vọng. Rồi cô thu xếp đồ đạc, lén bỏ nhà đi ngay đêm hôm đó, để lại 1 mảnh giấy dặn mọi người yên tâm.

Lisa đến Boston và thuê nhà sống ở ngay đó. Cha mẹ nhiều lần viết thư khuyên nhủ nhưng Lisa không trả lời: “Mình đã làm hại Brent, mình sẽ không bao giờ về nữa”. Đó là ý nghĩ trẻ con của cô gái 19 tuổi.

Rất lâu sau, cô vô tình gặp lại người láng giềng cũ: bà Nelson.

– Tôi rất tiếc về chuyện của Brent… – Bà ta mở lời.

Lisa ngạc nhiên:

– Sao ạ…

Bà Nelson nhanh chóng hiểu rằng Lisa không biết gì. Bà kể cho cô nghe tất cả: xe chạy với tốc độ quá cao, Brent đi cấp cứu, các bác sĩ tận tâm nhưng Brent không qua khỏi. Ngay trưa hôm đó, Lisa quay về nhà.

Cô ngồi lặng yên trước chiếc hộp. Cô không thấy tờ biểu đồ ngày xưa kín đặc các gạch chéo mà lại có 1 tờ giấy lớn:

“Lisa yêu quý,

Em không muốn đếm những lần mình tha thứ, nhưng chị lại cứ muốn làm điều đó. Nếu chị muốn tiếp tục đếm, hãy dùng tấm bản đồ mới em làm cho chị.

Yêu thương,

Brent”

Mặt sau là 1 tờ biểu đồ giống như Lisa đã làm hồi bé, với rất nhiều ô vuông. Nhưng chỉ có 1 ô vuông đầu tiên có đánh dấu và bên cạnh là dòng chú thích bằng bút đỏ: “Lần thứ 491: Tha thứ, mãi mãi! “

Parsing XML with Ruby

Tháng Hai 17, 2009

Source: http://railstips.org/2008/8/12/parsing-xml-with-ruby

Just for kicks and giggles, I decided to parse xml with each of the main libraries in Ruby (REXML, Hpricot, libxml-ruby), so I could see the differences between them in both API (getting at elements and attributes) and speed. I did two different xml formats. The first, Delicious, uses an attribute based approach, and the second, Twitter, uses a more elemental one. If you look at the xml files linked below, the previous sentence might make more sense.

Note: This is not for scientific and speed purposes but rather to get a feel for each of the libraries and how you traverse xml nodes and such with them.

The XML

Here are the files I used for reference. You’ll have to view source once you click on one of these links to actually see the xml.

  • posts.xml – Uses xml element for object (post) and xml attributes for object attributes
  • timeline.xml – Uses xml element for object (status) and child xml elements for attributes

REXML

Pros: In the standard library
Cons: Slow, I don’t like the name

%w[benchmark pp rexml/document].each { |x| require x }

##################################
# Parsing Delicious API Response #
##################################
xml = File.read('posts.xml')
puts Benchmark.measure {
  doc, posts = REXML::Document.new(xml), []
  doc.elements.each('posts/post') do |p|
    posts << p.attributes
  end
  # pp posts
}

################################
# Parsing Twitter API Response #
################################
xml = File.read('timeline.xml')
puts Benchmark.measure {
  doc, statuses = REXML::Document.new(xml), []
  doc.elements.each('statuses/status') do |s|
    h = {:user => {}}
    %w[created_at id text source truncated in_reply_to_status_id in_reply_to_user_id favorited].each do |a|
      h[a.intern] = s.elements[a].text
    end
    %w[id name screen_name location description profile_image_url url protected followers_count].each do |a|
      h[:user][a.intern] = s.elements['user'].elements[a].text
    end
    statuses << h
  end
  # pp statuses
}

Hpricot

Pros: Cool name, created by _why, faster than REXML, also does HTML, creative API
Cons: Not as fast as libxml-ruby, more of an HTML parser linguistically (ie: uses innerHTML instead of text or content, etc.)

%w[benchmark pp rubygems].each { |x| require x }
gem 'hpricot', '>= 0.6'
require 'hpricot'

##################################
# Parsing Delicious API Response #
##################################
xml = File.read('posts.xml')
puts Benchmark.measure {
  doc, posts = Hpricot::XML(xml), []
  (doc/:post).each do |p|
    posts << p.attributes
  end
  # pp posts
}

################################
# Parsing Twitter API Response #
################################
xml = File.read('timeline.xml')
puts Benchmark.measure {
  doc, statuses = Hpricot::XML(xml), []
  (doc/:status).each do |s|
    h = {:user => {}}
    %w[created_at id text source truncated in_reply_to_status_id in_reply_to_user_id favorited].each do |a|
      h[a.intern] = s.at(a).innerHTML
    end
    %w[id name screen_name location description profile_image_url url protected followers_count].each do |a|
      h[:user][a.intern] = s.at('user').at(a).innerHTML
    end
    statuses << h
  end
  # pp statuses
}

libxml-ruby

Pros: Blistering fast
Cons: Hpricot has cooler name, REXML and Hpricot both feel easier to use out of the box

%w[benchmark pp rubygems].each { |x| require x }
gem 'libxml-ruby', '>= 0.8.3'
require 'xml'

##################################
# Parsing Delicious API Response #
##################################
xml = File.read('posts.xml')
puts Benchmark.measure {
  parser, parser.string = XML::Parser.new, xml
  doc, posts = parser.parse, []
  doc.find('//posts/post').each do |p|
    posts << p.attributes.inject({}) { |h, a| h[a.name] = a.value; h }
  end
  # pp posts
}

################################
# Parsing Twitter API Response #
################################
xml = File.read('timeline.xml')
puts Benchmark.measure {
  parser, parser.string = XML::Parser.new, xml
  doc, statuses = parser.parse, []
  doc.find('//statuses/status').each do |s|
    h = {:user => {}}
    %w[created_at id text source truncated in_reply_to_status_id in_reply_to_user_id favorited].each do |a|
      h[a.intern] = s.find(a).first.content
    end
    %w[id name screen_name location description profile_image_url url protected followers_count].each do |a|
      h[:user][a.intern] = s.find('user').first.find(a).first.content
    end
    statuses << h
  end
  # pp statuses
}

Conclusion

I’ll probably start using libxml-ruby but Hpricot is more fun (and I’ve used it a ton). Oh, if you are curious, this was the output from the scripts above on my machine.

=rexml
delicious     0.020000   0.000000   0.020000 (  0.021139)
twitter       0.940000   0.020000   0.960000 (  0.988666)

=hpricot
delicious     0.010000   0.000000   0.010000 (  0.005548)
twitter       0.250000   0.010000   0.260000 (  0.258320)

=libxml-ruby
delicious     0.000000   0.000000   0.000000 (  0.007829)
twitter       0.030000   0.010000   0.040000 (  0.034040)

The twitter one is slower because of the loops and hashes most likely. I doubt it has much to do with the actual parsing, though it is a larger file and would be a bit slower.

jQuery on Rails: Why Bother?

Tháng Hai 17, 2009

Source: http://railstips.org/2008/11/20/jquery-on-rails-why-bother

A few people have suggested that I post about how to use jQuery with Rails. I thought about it and felt that others have already covered it quite well but why not collect their posts here for you to enjoy, right? Plus, I do all my JavaScript from scatch so I do not really ever use the helpers Rails provides and as such could not post intelligently on them.

So John, When Did You Quit Prototype?

I haven’t! I do not intend to ever quit using Prototype. Honestly, I have used jQuery quite a bit less than Prototype. I have found that jQuery and Prototype are both great and in different situations I will use a different library. The one thing I will say is even if you don’t actually switch to jQuery, I think it is important to learn new things and stretch yourself. It is good to feel frustrated and like a beginner. Also, jQuery takes a very different approach which has actually helped me write better Prototype code. Hope this is helpful and not overwhelming. :)

Creating A Plugin

Addicted to New jQueryToday, I wrote an article on How to Create a jQuery Plugin From Scratch over on my Addicted To New site. I picked out the most basic thing a plugin could do and explained each step in a lot of detail. Give it a read if you are into Prototype but are curious about jQuery.

Live Search and Fancy Zooming

Ordered List jQueryAfter creating my live search with quicksilver for prototype example, I decided to port it to jQuery (view demo). Then, humbly, I was corrected by the jQuery man himself, John Resig, who re-ported my port in a more jQuery-ish functional style. For those that are curious, I also massaged the AJAX-RDoc project to use quicksilver searching. This is really helpful when you can’t quite remember a method name.

Likewise, when I created fancy zoom for prototype, my partner in crime, Steve Smith, created a port of fancy zoom for jQuery (view demo). Fancy Zoom is great for showing text and images with an Apple-esque, in page zoom transition or even Flash if you have a video you would like to feature.

jQuery Railscast

RailsCasts jQueryRyan Bates did an awesome job showing how to use the jQuery on Rails plugin with Rails in a recent screencast. He also gave a really quick example on how to create a plugin. I would recommend watching this and subscribing to his Railscasts, which are great.

jRails Plugin

RailsCasts jQueryjRails is a drop-in jQuery replacement for Prototype/script.aculo.us on Rails. Using jRails, you can get all of the same default Rails helpers for javascript functionality using the lighter jQuery library. Ryan shows how to use it in the screencast mentioned above, but I thought I would also mention it separately. If you are a fan of the Rails javascript/ajax helpers, this plugin is for you. It makes each of them work with jQuery and has some nice demos on the site.

Link Love

While dispelling the myth that Rails is tied to Prototype, DHH gave some jQuery examples.

Brandon showed how he includes the authenticity token using prototype and the pug automatic shows how to do the same using jQuery.

Ben Curtis has a tutorial on how to do drag and drop sorting with jQuery and Rails.

Yehuda Katz has a year old presentation on jQuery and Rails that is still worth a look.

Nutrun has a more full post on how to do unobtrusive ajax with jQuery and Rails

ErrTheBlog (errtheblog is dead. long live errtheblog!) gave jQuery some serious love a while back in their jSkinny article. Chris also created a plugin named Facebox that is used extensively on GitHub and has a short post that shows how to get jQuery working with respond_to.

If you are a fan of Low Pro, Dan Webb has created a port of Low Pro for jQuery. (article #1, article #2)

In some Rails Rumble observations, it was noted that jQuery was more widely used than Prototype.

Don’t forget that “jQuery UI provides abstractions for low-level interaction and high-level, themeable widgets, built on top of the jQuery JavaScript Library, that you can use to build highly interactive web applications.” Be sure to check out the demos.

If you are a fan of Twitter, you can follow jQuery for links to articles and such.

Nathan Smith gave a crash course on jQuery that includes a sweet airline seat demo.

jQuery does not come with all of Prototype’s functionality out of the box, but you can usually find a plugin that does what you need if you are too lazy to make something yourself.

Lastly, one of my favorite jQuery resources is Visual jQuery. I found this site a blessing when I was trying to learn jQuery.

Feel free to post your favorite jQuery/Rails resources as a comment below.