Sunday, July 27, 2008

Ruby inheritance Gotcha!

Not much time for blogging right now, as we are officially putting our product out on Friday August 1 (I'll give more info about that later), but I did want to quickly mention an interesting gotcha I ran into today.

This is an embarrassing mistake, because if I had RTFM'd for the ruby language then I wouldn't have had any problems, but in case anyone is frantically searching for the same answer, here's the issue:

Let's say you are subclassing a library class, like so:


class MyClass < ThirdPartyClass
end


Now, ThirdPartyClass defines an instance method called "party_on" (which returns "true" if it successfully parties, and false if otherwise). This is used many places throughout the code. You would like to override it in your subclass so that you can run an extra check before executing the method. If you come from another language where "super" is basically a pointer to the parent instance, you might write your code like this:


class MyClass < ThirdPartyClass
def party_on
if self.has_class_tomorrow
raise "No party tonight, must study!"
end
super.party_on
end
end


If you did this, you might be confused at the error output:


NoMethodError: undefined method `party_on' for true:TrueClass


What's going on here? Is my super class the "True" class that represents the boolean constant true? No, the deal is that ruby is a little different from that other language you're used to. "super" is not a pointer to the parent instance, it's a method call that executes the same method name that you are currently in on the parent class (basically it passes the message up one layer in the hierarchy). You can pass parameters to it and everything doing "super(parm1,parm2)". The correct way to write the above code is like this:


class MyClass < ThirdPartyClass
def party_on
if self.has_class_tomorrow
raise "No party tonight, must study!"
end
super
end
end


Hope someone benefits from that!

Friday, July 25, 2008

Engine Yard: Great Hosting Company

The startup I'm working on is launching in a week, so I haven't had a lot of time for blogging. However, I had such a great experience yesterday with EngineYard that I had to put up a post giving them my whole-hearted recommendation.

For anyone who doesn't know about EngineYard, they are a web hosting company dedicated to providing exclusively Ruby-on-Rails hosting with the best customer service imaginable. You pay for that service in hosting costs ($400 monthly per "slice"), but it's worth every penny. Just yesterday, they were busy setting up my app when they came across a problem that was causing the mongrel servers to start up a little slowly. Now Daniel, the guy assigned to set up my account, didn't just email and say that there was something in my app causing problems. He actually dug into the code, found out specifically what was wrong, and gave me a few recommendations as to what the best path would be for taking care of it. These guys are pros, and I'm really impressed. Admittedly, I've only been with them a few days, but if that first experience with EngineYard is any indication, this is going to be a long and happy relationship.

EngineYard team, You guys rock! (especially Daniel Neighman)

Saturday, July 19, 2008

People Skills

Yesterday, I didn't get to do much software development. I spent the day in Overland Park, KS talking to a potential client and one of our data providers; it was a nice break actually. Present at both of those meetings was a man I hadn't met before, we'll call him "Steve", and Steve is someone of whom I'm extremely jealous.

You see, Steve is a member of the sales staff for our data provider, and in the course of the day he changed every one of my preconceptions about what a salesman is.

I've always seen salesmen as slimy guys with a smooth demeanor and a fake smile; Steve is a very warm person who is genuinely happy to meet you.

In my head salesmen are just pushing their product all the time; Steve wants to know how your family is doing, and he remembers every one of their names.

In traditional Dilbert-esq style, I imagine salesmen as just concerned about making the sale no matter what they need to promise the client; Steve will tell you about everything his company's product does, and will truthfully answer questions about what it doesn't do, but in the process he makes it seem so reasonable for them to have left that feature out (and when you think about it, it IS reasonable, and the reason is that he knows the software developers at his company personally and keeps up with the challenges they face).

I've imagined salesmen as commission-chasers, spending all their time working on getting that fat bonus; Steve is on the local school-board.

In my head, salesmen are all about "networking", calculating how relationships will benefit them; Steve likes talking to you about shared interests, and he doesn't even know what you do yet or whether having you as a friend will help him in any way.

As a result of all the points I mentioned above, I just can't help but want to work with this guy, and if our company ever makes it to the point where we need a sales-staff, I'm going to be looking for a genetic clone of Steve. I honestly don't think you can LEARN to be like him. Anyone who tried to teach themselves to be as friendly and selfless as him would just seem forced and calculating. Can you improve your people skills with some effort? Sure, but this man is a natural. Can your company afford NOT to have a representative like this guy?

Wednesday, July 9, 2008

Refactoring in Ruby

In my last post, I wrote a code-snippet that admittedly was not a very good example of well-refactored ruby. I'll let you go find it yourself, since I have no desire to link to something that embarassing ;), but I thought today I'd show that I learn from my mistakes by walking through some refactoring I did on my startup's app this morning.

First of all, what is refactoring? (Yes, somebody might be reading this who doesn't know). You can see this wikipedia entry for a complete description, but the short version is this: refactoring is changing the code without changing it's behavior. Ideally, after you refactor, the code does the exact same thing it did before. The difference is that it also:

(a) is easier to read
(b) contains less duplication
(c) is less complex, and
(d) is more flexible towards future changes.

So without any further ado, here is my starting code:


class SomeModel < ActiveRecord::Base
has_many :objectives
has_many :activities

def stats_to_json
json = "[["
load_json_objects(self.objectives,json)
json << "],["
load_json_objects(self.activities,json)
json << "]]"
return json
end

private
def load_json_objects(collection,json)
i = 1
collection.each do |item|
json << "{display:\"#{item.name}\",value:\"#{item.id}\"}"
i += 1
if i <= collection.length
json << ","
end
end
end
end


This does what I want it to, it takes the objectives and activities collections from the ActiveRecord associations and transforms them into a simple JSON array with a "display" member and a "value" member for each object (this is useful for me when I'm generating

Tuesday, July 8, 2008

Revelations from Rails Source 4

This is part four of my series of lessons learned from reading the rails source code
<<PART 3

Back from vacation, did some code reading through ActiveSupport's core extensions. Here's a few neat items:

---------------------------------------------------------------

10


Questionable code in object to_query conversion:

ActiveSupport adds two new methods to Object in the "conversions" file of it's core extensions ("rails/activesupport/lib/active_support/core_ext/object/conversions.rb"), and there's a small redundancy that I'm not sure I understand. The first method added is "to_param", which is just an alias of "to_s":

class Object
def to_param
to_s
end
end

No big deal. The second method is a handy one (that I didn't even know about) that lets you convert any object to a URL query string parameter (paired with a given key) with all special characters automatically escaped:

class Object
def to_query(key)
"#{CGI.escape(key.to_s)}=#{CGI.escape(to_param.to_s)}"
end
end

What is strange about it to me is in the second interpolation block #{CGI.escape(to_param.to_s)}, the code calls to_param, and then calls to_s on the result. If I read the aliasing of "to_param" above correctly, then calling to_s on the result is redundant since to_param already calls to_s internally, so you would just be calling to_s on a string, which just returns itself (an unnecessary step). Note that this is a big deal, there certainly wouldn't be a big performance hit to it or anything, it just seems pointless. Perhaps someone else will see something here that I don't and enlighten me.

Edit:Thanks to those of you who set me straight on this one in the comments. It is indeed true that "to_param" could easily be overriden in a subclass to return something that ISN'T a string and would have to be converted. I must not have been totally awake when I wrote this post this morning! ; )

---------------------------------------------------------------

11


Array "random element" core extension:

This one is from the "random_access" rails core extension to the Array class ("rails/activesupport/lib/active_support/core_ext/array/random_access.rb"). It's really simple, but nice to know about. Ever just wanted to pick an element from an array at random? Inside a rails app, you can just do the following:

x = [1,2,3,4,5].rand

the "rand" method on the array class is defined as follows:

def rand
self[Kernel.rand(length)]
end


so as you can see, it simply generates a random index based on the arrays length, and returns that element from the array.

---------------------------------------------------------------

12


Integers know if they are even or odd:

This one is easily forgotten, but comes in handy when you want to alternate something within a loop since you don't have to use a flag (just the iteration number). There is a core extension on integer that lets integer objects decide whether they are even or odd (located at "rails/activesupport/lib/active_support/core_ext/integer/even_odd.rb").

It's very simple, but easy to forget about. All you have to do is this:

i=0
while i < 10 do
puts ((i.even?) ? "even" : "odd")
i += 1
end


EDIT:I'm afraid that the code sample above betrays my java background. Some habits die hard, ; ). As "Anonymous" pointed out below, there is a better way to write the above snippet. See his comment for details.

It works the same way for the "odd?" method, just returning a boolean flag indicating the truth of the statement. The same module also defines the "multiple_of?" method, which takes one argument and does exactly what you'd think it does:

> 10.multiple_of? 2
#true
> 10.multiple_of? 3
#false

Friday, July 4, 2008

Advanced Rails

I got a new book a few days ago to take on vacation with me, and I've been enjoying it immensley. It's called "Advanced Rails", authored by Brad Ediger and put out by O'Reilly. I'm still ON vacation, so I won't be speding too much time blogging, but I will say that Mr. Ediger did a great job of puttiing out a book that doesn't cater to the lowest common denominator. Usually in educational books like this one, you have to start as if the reader knows NOTHING about the topic, and that can result in an experienced reader having to filter and skim trying to find the relavent content. With "Advanced Rails", although it wasn't like I knew NOTHING that was covered in the book, most of it was very useful and even paradigm shifting in some instances. I particularly appreciate his point early on (maybe chapter 2 or 3) about how important it is to read through the rails source code, not just to learn about how the rails framework works under the hood, but also to view some ruby code written by good developers. I've started the practice myself (as evidenced by my last three blog posts) and I've already started to learn a ton that way. Anyway, the book is full of good tactics for the aspects of your rails application that aren't always covered well in the beginner's rails literature (performance, security, etc). Great job, Brad, and thanks for the work you've done. I'd recommend "Advanced Rails" for anyone who's written a few apps in rails and wants to really deepen their understanding of the framework they're working with.

Wednesday, July 2, 2008

Revelations from Rails Source 3

This is part three of my series of lessons learned from reading the rails source code
<<PART 2PART 4>>

Woke up this morning, did some more reading through the ActionController module. Here's a few points of interest:

---------------------------------------------------------------

7


asterisk operator for the array:

Here's a trick I hadn't seen before, but might be handy. Ever had an array of numbers (or words) and wanted to print them out as a comma delimited list? You COULD do this:


arr = ["Red","White","Blue"]
str = ""
i = 0
while i < arr.length do
str << arr[i]
str << "," if i < (arr.length - 1)
i += 1
end
puts str


or, using the asterisk method of array, you could do this:


str = ["Red","White","Blue"] * ","
puts str


I know which one I prefer.

EDIT: As cypher pointed out in his comment below, the "join" method of the array class can be used to do the same thing. It should be noted, though, that you can pass an integer argument to the "*" method, and it will produce an array that is a concatenation of the original arrays contents repeated as many times as the passed in integer (join does not replicate that behavior). Thanks, Cypher!

---------------------------------------------------------------

8


class variable access:

much like attr_accessor for instance variables, and mattr_accessor for module-level variables, "cattr_accessor" (available through active support) is an available helper for use with classes when you want to expose their variables. For example:

class MyClass
@@data_var = "value"
end

currently the "data_var" class variable is only accessible inside the class. If you want to expose it for checking and modifiction, you can do the following:

class MyClass
@@data_var = "value"
cattr_accessor :data_var
end

Now you could access it from outside through the line "MyClass.data_var" or "MyClass.data_var = X".
---------------------------------------------------------------

9


Offloading static content hosting to another server:

So your rails servers are pretty tasked the way things are, and you'd like to not waste their time serving up images, stylesheets, and javascript files. Unfortunately, that's a pain to accomplish, right? I mean, you'd have to go change every URL in your view code to grab resources from the new server.

Not true, so long as you've followed good practices up until now. If you've been using "<%= stylesheet_link_tag %>" for your CSS pages, and "<%= javascript_include_tag %>" for your javascript files, and "<%= image_tag %>" for your images, then you're already set up for an easy transition.

ActionController::Base has a class variable called "asset_host" (exposed by cattr_accessor :asset_host, as discussed in tidbit 8 above), which defaults to an empty string. If you set it to be "http://www.your_static_server.com" (maybe in environment.rb), the tags mentioned above for images, javascript, and CSS will automatically prepend that address to every call for static data, thus allowing your rails servers to focus on what they do best. The line would look like this:

ActionController::Base.asset_host = "http://www.your_static_server.com"

Tuesday, July 1, 2008

Revelations from Rails Source 2

This is part two of my series of lessons learned from reading the rails source code
<<PART 1 PART 3>>

Here's another set of interesting tidbits I learned while perusing the rails source this evening:

---------------------------------------------------------------

4


Filtering private content:

There's a useful helper method built into ActionController that you can use to keep a "private" page from being seen by anyone except a request from the local server machine itself (appropriately named "local_request?". If you wanted, for example, to have a simple page that printed out information about the current version of the application, some data regarding session states or counts, or anything like that which you'd want to be able to access easily, you wouldn't want it to be available to anybody who just happened to stumble upon the correct URL. Here's how you could avoid that:


class MyController < ApplicationController
def app_info
if local_request?
render :inline => ApplicationWizard.info
else
render :text => '

No info for you!

', :status => 500
end
end
end


in the above code sample, you can see that only requests that pass the "local_request?" test actually get to see the information about the app (only requests from 127.0.0.1). Anything from outside would be harmlessly deflected with a 500 status code.

---------------------------------------------------------------

5


Ruby's Load Path

OK, please don't laugh at me for not knowing this before today, sometimes you can go quite a distance with a language and miss some of the basics: The load path in ruby is represented by the global variable "$:" (dollar sign, followed by a colon). Basically, it's an array containing all the directories that will be searched when you "require" a file. What's cool about this is that adding a directory to the load path programmatically is easy as cake. Check out this sample:


$:.unshift "/path/to/your/directory"


That's it. Using the "unshift" method for the array class, you've prepended your directory to the front of the array. Next time you require a file, if it's in that directory (or any of the others in the load path) it will be loaded.

EDIT: As Xavier pointed out in his comment below, "$LOAD_PATH" is a more clear alternative for the same array. Thanks, Xavier!

---------------------------------------------------------------

6


Ruby varargs

Want to pass a different number of items into a method each time, depending on your circumstances? It's easily doable using the varargs syntax for ruby. Admittedly, this is really just some syntax sugar since you could easily package the items into an array before calling the method and pass them as one object that way, but it cuts out an unnecessary step. Observe:


def print_colors(*colors)
colors.each {|c| puts c}
end

print_colors "Red","Yellow","Green","Brown"


By using the asterisk before the parameter name, ruby knows to accept the arguments you send in and to package them up in an array to be neatly presented to your method body.

Revelations from Rails Source 1

This is part one of my series of lessons learned from reading the rails source code
PART 2>>

It's been a goal of mine for some time to read through the rails source code to get a better feeling both for the rails framework's internal workings, and for the ruby language as a whole. In order to motivate myself, I'll be doing posts like this one in a series from time to time where I'll catalogue some of the things I learn while reading the code.

---------------------------------------------------------------

1


Easy Version Checking:

sure, you can use "rails -v" at the command line to find out what version you're currently using on your system, but there's also a way to get a complete printout of your version information for each of the rails modules, for your gems server, and for your ruby install, all in one command. From the home directory of your rails application, run the following:

$> ruby script/about


---------------------------------------------------------------

2


Module-level variable access:

ActiveSupport ships with a neat helper method, "mattr_accessor", to solve the problem of module-level variable access. For example, if you define a module variable in your code...

module MyApp
module MyMod
@@moduleVar = "value"

def do_stuff
puts "done"
end
end
end

...You don't have access to that value from outside the module.

irb> MyApp::MyMod.moduleVar
NoMethodError: undefined method "moduleVar"

You could, of course, build your own accessors, but that's kind of a pain, and repetitive if you have more than one configuration variable. With ActiveSupport, though, it's as easy as "attr_accessor" is for instance variables.

require 'active_support'
module MyApp
module MyMod
mattr_accessor :moduleVar
@@moduleVar = "value"

def do_stuff
puts "done"
end
end
end

And there you have it:

irb> MyApp::MyMod.moduleVar
"value"


---------------------------------------------------------------

3


Adding convenience methods to objects:

I found this bit in the file "rails/railties/builtin/rails_info/rails/info.rb", and it's something I've never seen before. This module declares a module level variable (an array of properties, to be specific) and then proceeds to add new methods to it using the "class << " syntax. I guess this makes complete sense, because when you write a block of methods inside "class << self" (to create class-level methods), something I've seen more commonly, you're adding methods to the "self" object, which in that context is the CLASS object, so there's no reason this shouldn't work, it's just something I hadn't thought of. Here's what it looks like:


module Info
mattr_accessor :properties
class << (@@properties = [])
def names
map &:first
end

def value_for(property_name)
if property = assoc(property_name)
property.last
end
end
end

class << self
... more code ...
end
end

So in this code sample, the "Info" module has a module-level variable, "properties", which is an array. It has all the regular array methods, plus two new ones, "names" (which prints the first value of each sub-array in "properties"), and "value_for" (which finds the sub-array of "properties" that has the parameter passed in as it's first argument).