Ruby Tip: Stop using puts object.inspect—use p instead

Posted by Trey Sat, 15 Mar 2008 21:36:00 GMT

I’ve just started reading the new ‘The Ruby Programming Language’ (the hummingbird, not the pickaxe) book by David Flanagan and Yukihiro Matsumoto (Matz). So far, it’s great. I picked up ruby like most of the other language I know—brute force through using it. While it’s nice to learn about things by researching what you need to address the current problem you’re facing, you do tend to miss some of aspects of the language. If you didn’t know it could be done, why would you go looking for how to do it? Usually, these are the aspects that set the language apart from others, after all, that’s why it’s not those other languages.

While I’ve read my share of ruby code by people who do know the language inside and out, I’ve finally decided to dig deep and learn about all of those things I skimmed over getting the general idea about how they worked.

So, through this process, I thought I’d share what I find in the book that I didn’t know before. Of course, you should probably set some time aside for yourself to cozy up with the book yourself.

First tip: ‘p object’ does the same as ‘puts object.inspect’. No more do you have to remember to add that .inspect when you are debugging and outputting stuff to the logger.

If we have a user, u:

>> puts u
#<User:0x1778d18>
=> nil
>> p u
#<User id: 3, username: "myusername", password: "2e14975672723cd9b93df192d2f45aa3b1d3ecb4", change_password: false, email: "myemail@email.com", firstname: "Test", lastname: "User", token: nil, token_expiration: nil, created_at: "2005-12-21 19:15:01", updated_at: "2006-01-12 06:39:17", logged_in_at: "2007-09-18 14:59:48", times_logged_in: 45, email_me: true, cancelled: false>
=> nil
>> 

Nice!

Using nginx as a load-balancing proxy to a mongrel cluster on Dreamhost 2

Posted by Trey Mon, 18 Feb 2008 18:27:00 GMT

There’s been a big push recently for Dreamhost to support rails better or for rails to be easier to support. Finally, those efforts are starting to pay off and Dreamhost is beginning to respond.

Now, with a few quick clicks of a button in Dreamhost’s panel (if you are using their Private Server service), you can have your rails app running under mongrel and being proxied through apache.

Not bad. In fact, it’s the easiest rails deployment I’ve seen barring the “we’ll set it up for you” kind. However, there’s still one glaring problem. Note the singularity of the word ‘mongrel’. That’s right, you get one, I repeat, one mongrel for your app. If you wasnt to perform the standard mongrel deployment of setting up a mongrel cluster and balancing the load between all of those mongrels, you’re back to being all on your own. What kind of rails app only needs one mongrel anyway?

I would love to migrate all of my rails apps over to my Dreamhost private server, but first I have to figure out how to balance the load between my many mongrels. Since, Dreamhost doesn’t let you touch your apache config, you can’t do the standard apache mod-proxy to mongrel cluster approach. You need another step. Apache to blank to mongrel clusters.

After investigating Pen, Pound, and Balance, all good options for the right circumstances, I decided I should get my hands dirty with that new server from mother Russia, nginx, that I’ve been hearing so much about.

Since nginx isn’t officially supported on Dreamhost, you’be got to compile and install you’re own. This actually turns out to be a good thing in this case, as there is a patched version of nginx that supports fair balancing instead of the round-robin approach used by the official stable branch.

Installing nginx

First, if you haven’t installed software on you Dreamhost account before, create a src directory in your home folder to store any source code you will download.

$ mkdir src

Now, nginx requires a few libraries to be present in order to work. From the nginx English wiki:

Requirements
  • gzip module requires zlib library
  • rewrite module requires pcre library
  • ssl support requires openssl library

We’ll be using all of these. Luckily, though, Dreamhost already has the openssl and zlib libraries installed. We just need to grab the pcre library. The latest version is 7.6.

Note: this might actually be installed on Dreamhost somewhere, but I was unable to find it.

Change into your source directory and download the library.

$ cd src
$ curl -O http://superb-east.dl.sourceforge.net/sourceforge/pcre/pcre-7.6.tar.bz2
$ tar -xjvf pcre-7.6.tar.bz2

Now, we aren’t actually going to install the library. Instead, we’re just going to tell nginx where the library is when we compile it, so it can grab the necessary chunks and get on with it’s business.

Next, let’s download that patched nginx so we can have fair balancing. If you for some reason don’t want fair balancing, you can get substitute the url below with this one: http://sysoev.ru/nginx/nginx-0.5.35.tar.gz

Still in the ~/src directory:

$ curl -O http://www.12spokes.com/nginx.git-upstream_fair-0.6.tar
$ tar -xvf nginx.git-upstream_fair-0.6.tar 
$ cd nginx.git
$ ./configure --with-pcre=/home/<your username>/src/pcre-7.6/ --prefix=/home/<your username>/local/nginx --with-http_ssl_module
$ make
$ make install

Note: I couldn’t figure out how to curl or wget this tarball from the git repository, so I downloaded it and put it in my directory for now. If anyone can figure out how to get it form the command-line, please let me know in the comments. If you want to get the file straight from the source, the url for the repo is http://git.localdomain.pl/?p=nginx.git;a=tree;h=upstream_fair-0.6;hb=upstream_fair-0.6

Now you have nginx installed on Dreamhost. You just need to set yourself up with a config file and you’ll be ready to start balancing those mongrels (fairly even). My config file is basically a combination of the default config file found in /home//local/nginx/conf and Ezra’s optimized config

Set up your mongrel clusters

If you don’t already, have some mongrels running, set some up:

$ cd /directory/of/your/rails/app
$ mongrel_rails cluster::configure -e production -p 8000 -N 3 -c /directory/of/your/rails/app -a 127.0.0.1

Then fire ‘em up.

$ mongrel_rails cluster:start

If you set everything up correctly, you should now have three mongrels running on ports 8000, 8001, and 8002. You’ll want to wrap this last command into a startup script, so you can feed it to cron and have monit monitor your mongrels, but that’s beyond the scope of this tutorial.

Configureing nginx

Now, in your nginx.conf file set up the cluster

upstream mongrel_yourapp {
    fair;
    server 127.0.0.1:8000;
    server 127.0.0.1:8001;
    server 127.0.0.1:8002;
}

Another thing you’ll need to change is the port that nginx listens to. Most of the examples on the web are using nginx to replace apache. Since this isn’t an option on Dreamhost, we’ll need to have nginx running on a different port. I use 8080.

server {
    # port to listen on. Can also be set to an IP:PORT
    listen       8080;

    ...

Starting nginx

Now, test your config file with the -t option and if everything is peachy, fire it up.

$ /home/<your username>/local/nginx/sbin/nginx -t
    2008/02/18 09:52:25 [info] 11891#0: the configuration file /home/<your username>/local/nginx/conf/nginx.conf syntax is ok
    2008/02/18 09:52:25 [info] 11891#0: the configuration file /home/<your username>/local/nginx/conf/nginx.conf was tested successfully
$ /home/<your username>/local/nginx/sbin/nginx

At this point, you have nginx running on port 8080. It then proxies to your mongrels running on port 8000, 8001, and 8002, keeping everything nice and even. We just need to tell Dreamhost to have apache proxy all requests to our application’s domain to nginx instead of trying to serve them itself.

Configure Dreamhost’s Proxy

Go to Domains->Mongrel and Proxy. Under ‘Set Up A Proxy Server Port’, choose the url for your application (leaving the path blank if your app serves the entire domain) and enter 8080, the port for nginx, into the ‘Port Number to Proxy’. Click the ‘Add Proxy Server’ and wait. After the standard Dreamhost 10 minutes to do anything passes, you should be able to go to your main url and see your application served up through all those little proxy tubes we just finished putting in place.

Voila.

The initial tests that I’ve performed shows a slight hit by having to still go through apache, but nothing too terrible. There’s probably a lot of other things we can do to optimize our applications before we get to that one. After I get some more benchmarking done, I’ll post my results.

Mountainwest RubyConf 2008

Posted by Trey Fri, 08 Feb 2008 22:14:00 GMT

I just registered for MountainWest RubyConf 2008. Ezra Zygmuntowicz and Evan Phoenix will be giving the opening keynote speech. It should be lots of fun. This will be my first conference, but since I’m getting into the Rails game full-time now, I figure I better start learning as much as I can. And hey, it’s not like I have to go anywhere to attend—it’s held in Salt Lake.

Register here

I’m still considering RailsConf. Anyone else going?

IE conditional comment helper for Rails 1

Posted by tieg Thu, 05 Apr 2007 00:10:00 GMT

These days, now that we have IE7, it’s common for those of us developing for the web to use conditional comments instead of CSS hacks to make sure our sites look good in different versions of Internet Explorer. (Or to pass anything else exclusively to IE)

I find myself using them on a regular basis, so here’s a little helper you can throw in your ./helpers/application.helper.rb to Rubify some of that commentage:

  # info at http://msdn.microsoft.com/workshop/author/dhtml/overview/ccomment_ovw.asp
  def conditional_comments(options={}, &proc)
    inverse    = options[:inverse] || ''
    comparison = options[:comparison] ? " #{options[:comparison]}" : ''
    version    = options[:version] || 5
    concat("<!--[if#{comparison} #{inverse}IE #{version}]>\n#{yield}\n<![endif]-->", proc.binding)
  end

Just put it in an ERb evaluation block and feed it a block of output:

<% conditional_comments :comparison => 'gte', version => 5.0 do
      stylesheet_link_tag 'layout_ie', 'typography_ie'
   end %>

Output:

<!--[if gte IE 5.0]>
<link href="/stylesheets/layout_ie.css" media="screen" rel="Stylesheet" type="text/css" />
<link href="/stylesheets/typography_ie.css" media="screen" rel="Stylesheet" type="text/css" />
<![endif]-->

It might be a little too much abstraction or processing for your tastes, but I was just a little sick of seeing the comments in every header. Yatta!

Simple CSS Text-Replacement Technique 2

Posted by tieg Tue, 27 Feb 2007 20:28:00 GMT

Problem

You’re building a navigation for your site and you want to use an image for the navigation, but also include text for screen readers and for markup’s sake.

news.png

Your markup looks like:

    <ul>
      <li><a href="">News</a></li>
    </ul>

Solution

First, we set the width and height of the LI to match the image, add a background on the anchor link, and make the anchor a block-level element so that we can give it a height and width:

li {width:150px;height:50px}
a {background:url(news.png);display:block;width:100%;height:100%}

news2.png

Next, we give the anchor link some padding-top so that the text drops below the image, and then set overflow:hidden on the li so that we can’t see the text below the image and the li stays the proper height.

li {width:150px;height:50px;overflow:hidden}
a {width:100%;height:100%;padding-top:50px;display:block;background:url(news.png)}

news3.png

You could also use padding-left or text-indent with this method.

This is a fairly common problem that has a couple different solutions, but this one tries to avoid extra markup like wrapping the text in a span, using an img tag, or using a negative padding/text-indent (I’m superstitious about that). The only restriction of this solution is that you have to know the height or width of the image you’re using.

Go Gigoit! 1

Posted by Erin Wed, 21 Feb 2007 07:02:45 GMT

Everybody, meet Gigoit. This pretty little app is designed for anyone who needs to get rid of some of their stuff. Think of it as Ebay for the do-gooder crowd. Say, for example, you have an old recliner in your apartment. It takes up a lot of room, and nobody ever sits on it, but it’s so big and bulky, you never get around to donating it. Maybe you’re the lazy type who’ll just put it out on the curb with a sign that says “free.”

Well, lazy types, I have good news for you. Gigoit is a great forum for you to list your unwanted items and give them away free. Just upload a photo and a description (using their wonderfully seamless forms) and wait for other people in your community to claim your unwanted possessions.

Gigoit is an updated form of freecycle.com, which uses clunky Yahoo user group messaging for its listings. This easy-to-use alternative is a fantastic way to give away (and get) things in an earth-friendly way. It’s recycling at its best. That it’s free and well designed is just icing on the cake.

Unfortunately, there aren’t a lot of users yet. But I’m sure we’ve all got stuff sitting around that we need to get rid of. Do your part and post something that you’ve been meaning to get rid of!

Prototype: New Site

Posted by tieg Thu, 18 Jan 2007 23:00:31 GMT

Woo! A new Prototype site with complete docs has been announced! Very nice.

"Web 2.0": Falling through The Gap

Posted by tieg Wed, 13 Dec 2006 07:02:00 GMT

After reading about how The Gap took a bit of time to do a site revamp, I took a look for myself and was a little shocked at their idea of a redesign. Just like many other mediums, you’ve gotta love the paradox in the Web world that a handful of people (or even just one) can make a beautiful, accessible site but a huge company with a lot of money and influence (enough to pay Common to be in their commercials) can’t top it.

Here are some things I would have asked before I gave the green light to launch this site:

1) Why on earth is the page optimized for a 800px wide browsing area, but there’s 33% dead air on the right? (read: horizontal scrollbar at bottom of screen)

Viewing Area

2) Why does my Sale Image look like a Photoshop 101 experiment that could be done some quick color and contrast manipulation? (Does anyone else see that thin brownish bar at the very bottom?)

3) Why did we pick this font?

4) Kudos to for the use of Flash. I’m a huge fan of small Flash widgets for logos (a la KEXP), but this logo seems uninspiring (and diminutive?).

5) What is that white space below the top navigation? Nothing ever shows up there.

White Space

6) More kudos to The Gap for their innovative AJAXish shopping experience (multiple products on the side of a product), but it seems way too complicated (especially considering the rest of the site looks simplified). One request for me on a product page (“The Rugged Romantic”) required 171 requests, 702 kb, and almost 15 seconds to load (this is on a Powerbook G4 on an okay wireless network).

7) The icons! What happened to the icons? Did they take a vacation to Zaxxon and never come back?

8) What’s up with the favicon being a solid black box?

9) What’s up with the inline styles?

10) Why doesn’t my site validate?

Disclaimer: this is partly just an exercise in site deconstruction, given that I might be liable to make the same mistakes.

In conclusion, the site works (and has some functionality of its contemporary “Web 2.0” sites), but it looks like a generic ecommerce site with not much to set it apart. With that said, most people just go there to shop, so I digress.

Accountability 1

Posted by stephanie Fri, 01 Dec 2006 16:35:00 GMT

A friend of mine found a very intersting site for visual people like me. Unfortunately, the data in this form hurts my heart. Today is World AIDS Day, Decemeber 1st. The theme this year is accountabilty. I belive there is no better theme considering which nations have massive resources and which nations have a destructive pandemic.

Worldmapper inflates countries by the statistical data collected. Take a look at some of these maps and use your sway and influence to make these maps look a little different next year.

Purchasing Power

Public Health Spending

HIV prevalence

Griping: It's not just for World Usability Day anymore! 1

Posted by Erin Wed, 15 Nov 2006 20:23:00 GMT

Here at 12 Spokes, we’re big fans of 37signals and their products. We use Basecamp, Campfire, and Backpack (not to mention the ur-product, Rails), for both work and play. We think they have a lot of good ideas for making websites great. They advocate user-centered design, thoughtful design, all the good stuff.

But today, their design really let me down. I’m calculating our company’s budget for the next year, and I remembered 37s blogging about paying for Basecamp in advance. It would be easier to crunch our numbers if I could pay it once every year and be done with it.

Since I couldn’t remember exactly what I’d read about pre-paying, I decided to check out Basecamp’s home page to find billing information. I was greeted by a page that scrolls and scrolls and scrolls, filled with acres of text. It has almost no conventional navigation; instead, the page is peppered (liberally) with blue inline links like “even looks great on paper,” “more buzz,” and “read our manifesto.” I was looking for a FAQ, so I looked in the places where FAQ links usually live.: At the top right of the page I found just a logo; At the bottom of the page (after a bunch of scrolling) I found a link called “Questions?” which I thought might mean “Frequently asked questions,” but it opened my email app. Ahh: when they say “Questions?” they mean “Contact us.”

I finally found the link to a FAQ. It is buried two-thirds down the screen, embedded in a section titled “Can we try it before we have to pay for it? What about refunds?” I follow the FAQ link and was relieved. It delivered me to a page with actual navigation! Aha! There’s the link called “membership/billing”! This is what I’m looking for!

It took me two or three minutes to find what I was looking for. Even funnier, once I’d found the FAQ, I decided to blog about my adventure, and I had to go through the whole thing again, because I couldn’t remember where (among all that damned blue text) I’d found the FAQ link!

The bottom line: Like Steve Krug preaches, we have web conventions for a reason. When you dismantle those conventions, usability suffers. No matter how many yellow highlights or yellow fades you use, no matter how “clean” your design.

Older posts: 1 2 3