Showing posts with label metaprogramming. Show all posts
Showing posts with label metaprogramming. Show all posts

Friday, January 25, 2008

Interfacing and distributing code as a language feature

Recently, I've been looking to send email from erlang. Despite all the cool things it does, its INets library doesn't have an SMTP client in it. Trapexit happened to be down this week, so I ended up hunting around on the web (next time, I should just ask on newsgroups).

I found ErlMail as part of an Erlang Software Framework suite, and it had a simple SMTP client in it. I was glad I didn't have to write one myself, but I found it didn't do authentication. it was written cleanly enough that I was able to patch in authentication without much of a problem, and submitted it to the maintainer.

The short experience made me pretty thankful that SMTP protocol is in plain text, rather than bit-packed. Since much of our general purpose languages are pretty good at manipulating text, it's comparatively easy to interface with it and write a wrapper for it.

However, it's a pity that for every new language that comes out, a new wrapper must be written for an SMTP client. Same goes for REST/SOAP interfaces for any number of APIs that we see out there, from Google maps to facebook apps.

Part of the problem is the mismatch in syntax of the protocol/interface and the language the programmer is working in. Simply looking at REST interfaces, there's no programming language that makes native method calls like /post?title=32?body=f1rst%20post. Not that would make sense to do so since there are other RPC (remote procedure call) protocols too.

The only way I can see out of it is for a language(or library) dynamically generate code that maps a native call syntax to a RPC syntax. For every new type of RPC interface (REST, SOAP, JSON, etc.), we'd have a single file that describes the mapping. Then, when a new service or platform comes out with a REST interface, you don't need to write a new wrapper for that interface.

However, lots of languages have different method invocation capabilities. Some need types to arguments, others can take first class functions or blocks, and still others can take an unknown number of arguments. I don't think it would be easy, but it'd be nice to have so we stop wasting our time writing interface wrappers. Maybe Lisp was on to something when it said code is data and data is code.

Tuesday, December 18, 2007

(Aha!) Part of the reason why great hackers are 10 times as productive

I knew in college that some dudes were faster than I was in terms of programming. Since peer programming wasn't exactly encouraged in college, and at work I did mostly prototyping work, I never really knew how fast other programmers worked.

So when I read Paul Graham (and Joel's) claim that great hackers are at least ten times as productive as average programmers (too lazy to cite right now), I was kinda shocked. Surely, ten times is an order of magnitude! Something that takes an average programmer a 40 hour week to do the great hacker can do in a 4 hour afternoon?

I wondered about that, since there are times when I get stuck on something, then I just start stabbing around randomly out of frustration. I had assumed that great hackers were faster only because they had either the experience or insight to side-step whatever I was doing wrong.

But lately, I've been re-reading everyone's essays that write about programming productivity. And one thing that caught my eye the second time around was when Paul Graham was talking about bottom up programming and how he didn't really believe in objects, but rather, he bent the language to his will. He was building new blocks for himself so he could think about the problem at a higher level of abstraction.

This is basic stuff! I mean, that's the whole point of higher-level programming. When you refactor methods out, you're creating a vernacular so that you can express the problem in terms of the problem domain, not in terms of general computing. This is much like if you want to drive a car, you'd want to be able to step on the gas, rather than time the firings of the pistons. And if you want to control traffic in a city, you'd rather tell all cars to go to a destination, rather than stepping on the gas and turning the steering wheel for each one.

But taken into the light of bending a language to your will, it makes it more clear for me as to how great hackers are ten times as productive. Great hackers are productive not only because they know what problems to sidestep and can problem solve systematically and quickly, but they also build a set of tools for the problem domain as they go along. They are very good pattern recognizers and will be able to generalize a particular pattern of code, so that they can use it again. But not only that, great hackers will create an implicit understanding attached to the abstraction, ie. what we might call common sense.

A case in point. Before Ruby, I'd used for loops over and over again, never really thinking that I could abstract a for loop. It wasn't until they were taken away in Ruby did I realize that map, inject, and their cousins are all abstractions of the for loop. When I see "map" I know that it performs a transformation on every element. But I also know that the array I get back will be the same size, that each element operation doesn't affect other elements, among other things. These are implicitly stated, and they allow for shorter code.

When that happens, you can simply read "map", and get all the connotations it comes with, and hence it comes with meaning. It also becomes easier to remember, since it's a generalized concept that you can apply in different places in the code. The more times you use it, the easier it is to remember, instead of having specialized cases of the same kind of code where the behavior is different in different parts of the code.

A great hacker will take the initial time upfront to create this generalized code, and will save in the long run being able to use it. Done over and over again, it all adds up. So it's not that for any given problem, a great hacker will be done in 4 hours what it takes an average programmer 40 hours, but that over time, a great hacker will invest the time to create a tools and vocabulary that lets him express things easier. That leads to substantial savings in time over the long haul.

I hesitated writing about it, as it's nothing I (nor you) haven't heard before. But I noticed that until recently, I almost never lifted my level abstraction beyond what the library gave me. I would always be programming at the level of the framework, not at the level of the domain. It wasn't until I started writing plugins for rails extracted from my own work and reading the Paul Graham article that a light went off for me. It was easier to plug things like act_as_votable together, rather than to still mess around with associations (at the level of the framework). I still believe you should know how things work underneath the hood, but afterwards, but all means, go up to the level of abstraction appropriate for the problem domain.

DSLs (Domain specific languages) are really just tool-making and vernacular creation taken to the level of bending the language itself. It's especially powerful if you can add implicit meaning to the vernacular in your DSL. It's not only a way of giving your client power in their expression, but it's also a refactoring tool so that you can better express your problem in the language of the problem domain. Instead of only adding methods to your vernacular, you can change how the language works. It was with this in mind that I did a talk on DSLs this past weekend at the local Ruby meetup. First part is on Dwemthy's Array, and the second is using pattern matching to parse logo. Both seemed pretty neat when I first read about it. Enjoy!




DSL in Ruby through metaprogramming and pattern matching

Tuesday, December 11, 2007

The user owns this and that

In most any community-based website, your users are creating objects. And sometimes, you'd only like to display them when they're owned by the user. Usually, it's easy enough to do the check based on the association in the template views.

<% if @story.account == session[:member] %>
<%= render :partial => "story"
<% end %>

However, for the sake of perhaps over-reaching, but something more readable, we try:

class Story < ActiveRecord::Base
belongs_to :account

def owned_by?(user)
self.account == user
end
end


<% if @story.owned_by?(session[:member]) %>
<%= render :partial => "story"
<% end %>

But this gets to suck, because you have duplicate code in different classes that are just slightly different due to association names. One way to solve it is to put it in a module, and include it in different classes. After all, that's what mixins are for.

module Ownership
def owned_by?(user)
self.account == user
end
end

class Story < ActiveRecord::Base
include Ownership
belongs_to :account
# blah blah blah
end

class Post < ActiveRecord::Base
include Ownership
belongs_to :account
end

Or alternatively, you can put it in the account, but in reverse. But now, you have to search through the associations of the owned ActiveRecord object.

class Account < ActiveRecord::Base
def owns?(ar_object)
ar_object.class.reflect_on_all_associations(:belongs_to).detect { |assoc|
ar_object.send(assoc.name) == self
} ? true : false
end
end

I find the tertiary operator to be kinda ugly there, but it doesn't make sense to return the reflection object. Regardless, this lets you do:

<% if session[:member].owns?(@story) %>
<%= render :partial => "story"
<% end %>

However, this doesn't work for self-associated AR objects, or objects that have two or more belongs_to to the same account. It relies on a unique belongs_to association for every object belonging to account. I'm not sure yet, which way's the better way to go, and in the end it probably doesn't matter as much, but I do like being able to say user.owns?(anything) for any object without really thinking about what the associations are. half-tip.

Thursday, December 06, 2007

Communicating your intent in Ruby

I've been using Ruby most everyday for about two years now. While I'm no expert, I know enough to be fairly productive in it. And beyond liking the succinctness and power that you often hear other people talk about, it's made me a better programmer. But there's an aspect of Ruby that worries me somewhat.

To start, programming is recognized rightfully as a means to build something from pure thought. But it's also a form of communication, to other programmers that will touch your code later, and to yourself when you look at it months from now. We're at a point that other than embedded and spacecraft programming, we have the luxury of using programming languages that focus ease for the programmer, rather than for the ease of the machine. Fundamentally, that's the philosophy that Ruby takes.

And while Ruby's nice in a lot of ways, I'm not sure about how it communicates an object's interface. When you're allowed to modify objects and classes on the fly, how do you communicate interfaces between modules you mixin and methods/modules you add? By interface, I mean, how do you use this class so that it does what it's suppose to? Normally, it's pretty obvious--you look at the names of the methods declared in the code. A well-written class has public methods exposed, or you look at its ancestor's public methods. You might need some documentation to figure out how to call them in the right order, but generally, you have some idea just by looking at the method signatures.

However, when you throw mixins and metaprogramming in the mix, it becomes less easy to tell just from looking at the method signatures in the code--the structure of the code. You have to specifically read the code, or you have to rely on someone who knew intent to document it in detail.

An example communicating interfaces for mixins: the module Enumerable contains a lot of the Collections related methods. The cool thing is that if you wanted these functions in your own class, all you have to do is define each() in your class, mixin the Enumerable module, and you get all of these "for free". However, outside of documentation explicitly stating it, it's not as immediately obvious in method signatures that this is what you have to do in order to use it. It's only after scanning through the entire code that you notice each() being used for all the methods.

Of course, Ruby contains enough metaprogramming power to protect yourself against this. one can do something like this:

class MethodNeededError < RuntimeError
def initialize(method_symbol, klass)
super "Method #{method_symbol.to_s} needs to be in client class #{klass.inspect}"
end
end

module Enumerable
def self.included(mod)
raise MethodNeededError.new(:each, mod) unless mod.method_defined?(:each)
end
end

This only works if you put the include after you define each(). That's just asking for trouble when the order of your definitions in your class matter.

A fair number of people are writing mini-DSLs in ruby using metaprogramming tricks. One of the common ones is the use method_missing to define or execute methods on the fly. ActiveRecord's dynamic finds are implemented this way. The advantage of communication of interface here in the structure of the code is obvious. Unless it was documented well, you can't tell just by looking at the method signatures.

Why do I harp on interface signatures? I mean, in the instance of requiring each(), it works by just letting it fail in the enumerated methods, since it'll complain about each itself. In the instance of method_missing, just read the regex in the body. While these are true, none of these allow for rdoc to generate proper documentation. The whole point of documentation is to show you the interface--how to use that piece of code. I'm just afraid that given Ruby's philosophy of being able to write clear, powerful, and succinct code, it might fall short when people start using these metaprogramming tricks like alias_method_chain and method_missing more and more. Maybe rdoc needs to be more powerful and read code bodies for regex in method_missing?. It already documents yields in code bodies, but that seems awfully specific.

I'm not a exactly a fan of dictating interfaces like in Java. When you're first coding something up, you're sketching, so things are bound to change. Having plumbing like interface declaration gets in the way, imo. However, when something's a bit more nailed down, it'd be nice to be able to communicate to other programmers your intent without them having to read code bodies all the time.

In the end, I side on flexibility. However, I kinda wish Ruby had some type of pattern matching for methods so I didn't have to read method_missing all the time. But then again, that would be messy in all but the simplest schemes. Can you imagine a class that responded to email addresses as method calls? I guess I'd have to file this one under "bad ideas"

Friday, November 16, 2007

State change observer for ActiveRecord

When I started writing some code recently, I noticed that my controllers were getting fat. There was much to do, but there was a bunch of stuff in there that didn't have anything to do with actually carrying out the action--things like sending notifications. ActiveRecord already has observers to take action on certain callbacks. However, what I needed was to take actions on certain state transitions. Not seeing any immediate solutions in the Rails API, I decided to test myself and try writing one. I was bored too. So while I'm not sure if it was worth the time writing it, it certainly was kinda interesting. Here's what I came up with:

Just as a contrived example, let's say we are modeling the transmission of a car. It has three modes: "park", "reverse", "drive". We want to send a notification when a user tries to change it from "reverse" to "drive", but not when he tries to change it from "park" to "drive". If it didn't matter, and we just wanted to send notifications when the state changed to drive, we'd just use the observers that came with ActiveRecord. But since we do care where the state transition came from, here's what I came up with:


class CreateCarTransmission < ActiveRecord::Migration
def self.up
create_table :car_transmission do |t|
t.column :engine_id, :integer, :null => false
t.column :mode, :string, :null => false, :default => "park"
end
end

def self.down
drop_table :car_transmission
end
end



class CarTransmission < ActiveRecord::Base
include StateTransition::Observable
state_observable CarTransmissionNotifier, :state_name => :mode
end


So then for my notifier I have:


class CarTransmissionNotifier < StateTransition::Observer
def mode_from_drive_to_reverse(transmission)
# send out mail and flash lights about how this is bad.
end
end


And that's it. Whenever in the controller, I change the state from "reverse" to "drive", lights will flash and emails will be sent out condemning the action, and my controllers stay small and lean.

class CarController < ApplicationController
def dismantle
@car = Car.find(params[:id])
@car.update_attribute :mode, "reverse"
@car.update_attribute :mode, "drive"
end
end


So where's the magic? It took a bit of digging around. There were two major things I had to do. I had to insert observers during initialization and I had to override setting of attributes to include an update to notify observers.

ActiveRecord doesn't exactly allow you to override the constructor. I don't think I tried too hard to mess around with it. Looking on the web, I happened upon has_many :through again, where he has some good tips that helped me through Rail's rough edges. While I didn't exactly follow his advice, I did find out about the call back, :after_initialize. It must be something new, because I don't see it in the 2nd edition of the Rails book, and the current official API doesn't list it. Other Rails API manuals seem to be more comprehensive, like RailsBrain and Rails Manual.

Then overridding attributes has always been a bit of a mystery. I found a listing of the attribute update semantics, which was helpful to figure out what I was looking for, but it was false, in that you can't use the first one (article.attributes[:attr_name]=value) to set an attribute. Looking in the Rails code for 1.2.3, it shows that attributes is a read_only hash. But it's right that you should override the second one (article.attr_name=value), since update_attribute() and update_attributes() depends on it.

Again, it ends up that the function I was looking for wasn't found in the official API as a method, other than a short mention in the description of ActiveRecord under Overriding Attributes, which makes it harder to find. Ends up that we can use write_attribute().

So that's pretty much it. Using some standard meta-programming like how plugins do it, you wrap it up, and it's pretty simple:

require 'observer'

module StateTransition
module Observable
class StateNameNotFoundError < RuntimeError
def message
"option :state_name needs to be set to the name of an attribute"
end
end

def self.included(mod)
mod.extend(ClassMethods)
end

module ClassMethods

def state_observable(observer_class, options)
raise StateNameNotFoundError.new if options[:state_name].nil?
state_name = options[:state_name].to_s

include Object::Observable

define_method(:after_initialize) do
add_observer(observer_class.new)
end

define_method("#{state_name}=") do |new_state|
old_state = read_attribute(state_name)
if old_state != new_state
write_attribute(state_name, new_state) # TODO yield the update method
changed
notify_observers(self, state_name, old_state, new_state)
end
end
end

end

end

class Observer
def update(observable, state_name, old_state, new_state)
send("#{state_name}_from_#{old_state}_to_#{new_state}", observable)
rescue NoMethodError => e
# ignore any methods not found here
end
end

end


I had a difficult time figuring out how to define methods for an instance of a class. The only thing I came up with was to use define_method, or to include a module with instance methods in them. instance_eval() didn't work. The meta programming for ruby gets rather confusing when you're doing it inside a method--it seems hard to keep track of which context you're in.

So if you can make a use of this, great. If you think it's worth moving it into a plugin, let me know that too. If you know of a better way, by all means, let me know. tip!

Wednesday, September 19, 2007

Diving into Rails source and explaining alias_method_chain in pictures

I've been involved with the local Ruby group, and I did a talk on diving into the Rails source code. I have to admit, I probably should have dove into it earlier, but there was a lot to learn just by using Rails, for someone that was doing engineering work before this. Originally, I was going to just relate my experience of when I had to dive into the code, but then I happened on Rails' Unusual Architecture, and it gave a good topic for introducing metaprogramming used in Rails.

At first, it was pretty confusing, since I came from a C++ background and was use to the idea of design patterns. Well, there are patterns, it's just that in dynamic languages, much of the traditional Gang of Four design patterns goes away.

I'll outline the meat of the talk. Rails doesn't use the Decorator Pattern. Instead it basically renames methods in calls to inject additional functionality that wraps around the original functionality. How does it do this? It uses something called alias_method_chain, detailed here and here.

And inside alias_method_chain, is a native method called alias_method. Since everything in Ruby is an object, and changeable, that means methods of modules and objects are also changeable. It basically makes a copy of the old method and calls it something new.

I made pictures to show the progression. Let's say we have a method called "save" that we want to enhance with "validation".


We start with ActiveRecord and the Validation module. So in our validation module, we make a method called "save_with_validation"(purple heart) that calls a method called "save_without_validation" inside it. "save_without_validation" doesn't exist yet, because we haven't called alias_method_chain().


Then our first step is to include the Validation module inside of ActiveRecord.

Then when we call alias_method_chain(:save, :validation), using alias_method, it'll make a copy of the original save method, and call it "save_without_validation".


Then, it'll rename the method inside of validation from "save_with_validation" to "save". This way, any code calling save() on ActiveRecord will execute the new save, which does validation first, and then turns around to call the original save (green sun). The client won't know any different, but in fact, code was injected between the original save (green sun), and the caller inside of the new "save" (purple heart). And the original save doesn't know any different either, since nothing's changed from its point of view.

In code, it'll look something like this:
class ActiveRecord
def save
# do saving stuff
end
end

module Validation
def save_with_validation
# do validation
save_without_validation
end
end

class ActiveRecord
include Validation
alias_method_chain :save, :validation
end

Which if we 'executed' the above as we did in pictures, it ends up being equivalent to:
class ActiveRecord
def save_without_validation
# do saving stuff
end

def save
# do validation
save_without_validation
end
end

I'm not sure how I feel about it as of yet, but at first glance, it's a nice pattern once you know what's going on. At first, I saw all these methods being called in the Rails source which aren't actually defined anywhere. It ends up it's because of metaprogramming stuff like this going on. I think other people have said this is bad idea because it's hard to inject functionality in the middle of chains that already exist. If you pick up one, you pick up everything before it. One might argue the same is true of Decorator patterns.

In any case, you'll see this repeated over and over again in the Rails source, so hopefully, this'll give you some idea of what's going on if you ever decide to go Rails splunking.

Sunday, May 13, 2007

Ruby Snippet: Caching object attributes

Here's another little snippet. I'm not sure if I'm extracting out boiler plate code prematurely, but it seems right.

A good general rule of thumb for refactoring is that one should always call an object for its value, rather than storing object values in temporary variables when you're using the object. Generally, you can get away with setting the value of an object to a temporary variable, and then using that temporary variables for subsequent calculations
# c = Collection.new((0..500).to_a)
collection_sum = c.sum
collection_sum * 3 + 2 # some calculation with the sum
if collection_sum == 4 # some comparison with the sum.
# do something else
end
You're essentially caching the value outside of the object, 'c'. This is good if 'sum' is an expensive call. However, if the code segment gets large, this method tends to get confusing, especially if you stored it in temporary variables at different times, etc. (Also a good rule of thumb is that your scope should never be bigger than about 10-20 lines) It's better to refer to the value directly from the object.
# c = Collection.new((0..500).to_a)
c.sum * 3 + 2 # some calculation with the sum
if c.sum == 4 # some comparison with the sum.
# do something else
end

This is not applicable to functional programming languages, since all variables are consts within a scope. But for object-orientated imperative languages, this generally makes for less messy code.

However, performance is a problem, if you have to calculate the sum each time you needed it. An easy solution would be to cache the value. An example would be summing the values across some collection. Normally, that wouldn't be a problem, except if you had hundreds thousand entries. If nothing was added to the collection, the sum would stay the same. If something was added, mark the collection to need updating, and then the next time sum() is called, update the value.

You'd need both a variable to keep track of whether the attribute needed updating, and another variable to hold the result. If you only had one attribute, that'd be ok. If you have more than one, it starts to get a little bit messy. This is where meta programming comes in. I wrote a piece of code that did the bookkeeping of caching attributes for you. You'd use it like:
class Collection
include AttributeCache

def initialize
@array = []
cache :sum, :initial => 0
end

def add(x)
outdate_sum
@array << x
end

def sum
cached_sum { @array.inject {|t, e| t += e} }
end

end

The code is simple. In the initialization method, there is a call to cache an attribute, sum. And then in the other methods, you'd mark where the sum would be outdated, and in the actual call to sum, you'd specify what to do to update the sum.
module AttributeCache

def metaclass; class << self; self; end; end

def cache(attr_name, options)
instance_variable_set "@#{attr_name}", options[:initial]
instance_variable_set "@#{:sum}_outdated", true

metaclass.instance_eval do
define_method("outdate_#{attr_name}") do
instance_variable_set "@#{attr_name}_outdated", true
end
end

metaclass.class_eval %Q{
def cached_#{attr_name}(&block)
if @#{attr_name}_outdated
@#{attr_name}_outdated = false
@#{attr_name} = block.call
end
return @#{attr_name}
end
}

end

end

The biggest hurdle was to figure out how to define a method that accepted a block with meta programming. The best I came up with was to use class_eval. If you have better suggestions, let me know. tip!

Sunday, April 29, 2007

Ruby Quiz #122 Solution: Checking Credit Cards using meta-programming

So this is the first time I actually did a RubyQuiz for real. I spent probably 3 or 4 hours on it. Not too shabby. And, I got to do a little bit of meta-programming! It's basic meta-programming, but I liked the solution. Brief intro to the quiz:
Before a credit card is submitted to a financial institution, it generally makes sense to run some simple reality checks on the number. The numbers are a good length and it's common to make minor transcription errors when the card is not scanned directly.

The first check people often do is to validate that the card matches a known pattern from one of the accepted card providers. Some of these patterns are:

      +============+=============+===============+
| Card Type | Begins With | Number Length |
+============+=============+===============+
| AMEX | 34 or 37 | 15 |
+------------+-------------+---------------+
| Discover | 6011 | 16 |
+------------+-------------+---------------+
| MasterCard | 51-55 | 16 |
+------------+-------------+---------------+
| Visa | 4 | 13 or 16 |
+------------+-------------+---------------+
There's more rules for each credit card at wikipedia. So normally, how would you do this with OO design? First thing that came to mind was creating a general CreditCard base class, and use polymorphism to implement the rule for each type of card, which is a subclass of CreditCard (i.e. Mastercard extends CreditCard). The problem with this, I've always found is that there's a proliferation of classes when you do something like this. People have solved this problem with other patterns, such as Factories, to build families of classes.

But that's a lot of structure that I didn't want to write for a little RubyQuiz. So I opted for case statements at first:
def type(cc_num)
case cc_num
when /^6011.*/
return :discover if cc_num.length == 15
when /^5[1-5].*/
return :mastercard if cc_num.length == 16
...other card rules...blah blah blah
end
return :unknown
end
But as we all learned from having to maintain a proprietary server program written in C nested 11 or 12 layers deep all in one main file, case statements suck and don't scale (guess who had to do that?). So what's a better solution? I'd like to think I came up with a nice one.

With dynamic programming languages, I find that a lot of the problems that design patterns solve simply go away. And with meta-programming, it can be a much more flexible tool to solve design problems, rather than with design patterns. In a way, I created a very very tiny domain specific language for checking credit card type and validity. All you need to do to use it is define the rules in the table above in your class which subclasses credit card checker:
require 'credit_card_checker'

class MyCreditCardChecker < CreditCardChecker
credit_card(:amex) { |cc| (cc =~ /^34.*/ or cc =~ /^37.*/) and (cc.length == 15) }
credit_card(:discover) { |cc| (cc =~ /^6011.*/) and (cc.length == 16) }
credit_card(:mastercard) { |cc| cc =~ /^5[1-5].*/ and (cc.length == 16) }
credit_card(:visa) { |cc| (cc =~ /^4.*/) and (cc.length == 13 or cc.length == 16) }
end

CCnum = "4408041234567893"
cccheck = MyCreditCardChecker.new
puts cccheck.type(CCnum) # => :visa
puts cccheck.valid?(CCnum) # => true
Neat! So this way, you can have any type of credit card checker you want, in any combination. And if suddenly there was a proliferation of new credit card companies, you can add them pretty easily. How is this done? Well, let me show you:
require 'enumerator'

class CreditCardChecker
def self.metaclass; class << self; self; end; end

class << self
attr_reader :cards

def credit_card(card_name, &rules)
@cards ||= []
@cards << card_name

metaclass.instance_eval do
define_method("#{card_name}?") do |cc_num|
return rules.call(cc_num) ? true : false
end
end
end

end

def cctype(cc_num)
self.class.cards.each do |card_name|
return card_name if self.class.send("#{card_name}?", normalize(cc_num))
end
return :unknown
end

def valid?(cc_num)
rev_num = []
normalize(cc_num).split('').reverse.each_slice(2) do |pair|
rev_num << pair.first.to_i << pair.last.to_i * 2
end
rev_num = rev_num.to_s.split('')
sum = rev_num.inject(0) { |t, digit| t += digit.to_i }
(sum % 10) == 0 ? true : false
end

private
def normalize(cc_num)
cc_num.gsub(/\s+/, '')
end
end
If you don't know much about meta-programming yet, you might want to try _why's take on seeing metaclasses clearly along with Idiomatic Dynamic Ruby. Don't worry if it takes a while...I was stumped for a while also.

Anyway, the magic is in the method credit_card. Notice it's between "class << self" and "end", which means that this method is defined in the singleton class of the class CreditCardChecker. But you can just think of it as a class method. Same thing with the method metaclass(), it is a class function that returns the singleton class of the caller.

Now, the thing is, this isn't very exciting in itself. However, notice that credit_card() is executed in the subclass MyCreditChecker. This means that when inside credit_card(), metaclass returns NOT the singleton class of CreditCardChecker, but the singleton class of MyCreditCardChecker! Then when we proceed to do an instance_eval() and a define_method(), we are defining a new method in the singleton class of the subclass MyCreditChecker. Inside the method, it will call the block that evaluates the rule given for that card. If true, it returns true and false if false. The only reason I did it that way, is so in case the block returns an object, it'll return true instead of the object.

Therefore, to any instance of MyCreditChecker, it will look like there's a class method with the name of the credit card. So if you did:
require 'credit_card_checker'

class MyCreditCardChecker < CreditCardChecker
credit_card(:amex) { |cc| (cc =~ /^34.*/ or cc =~ /^37.*/) and (cc.length == 15) }
end
MyCreditCardChecker.amex?(cc_num) would be a valid method that checks if the credit card number is an American Express Card. And what cctype() method does is that it cycles through all the known credit cards and returns the first one that's valid. The rest is standard fare, so I won't go through it.

And oh, btw, each_slice() and each_cons() got moved to the standard library, so you have to include enumerator in order to use it--even though the official ruby docs say that it's still in the Enumerables class in the language.

Friday, March 16, 2007

Keep users from looking at other people's data with a simple ownership filter

Happy St. Patrick's day everyone!

Well. Everyone's pretty familiar with authentication. That's where you force the users to login, before you'll show any of the pages. Usually, this is achieved with a before_filter, so that you're not checking if a user has logged in in the beginning of each action in the controller. This keeps your code mighty DRY. But what about ownership of data? Within any web app, you have data that's owned by some users, and other data that's owned by other users. Just because they're logged in doesn't mean that they should be able to see other users' data.

Oh, these tables of mine

A good example are friends in a social network app. Each user has a set of Friend records in the database that belongs to them. (btw, don't use the User table below in your own app. you never want to store cleartext passwords in the database. Check out authentication tutorials)
create_table :users, :type => "InnoDB" do |t|
t.column :username, :string
t.column :password, :string
end

create_table :friends, :type => "InnoDB" do |t|
t.column :user_id, :string
t.column :name, :string
t.column :email_address, :string
end

create_table :posts, :type => "InnoDB" do |t|
t.column :user_id, :string
t.column :timestamp, :datetime
t.column :body, :text
end

Your first instinct sucks

You only want those records of friends that belong to them to be available to them. So what's the first thing that you're inclined to do? Assume that you have the User record as an indication of being logged in the session data.
class FriendController < friends =" Friend.find(:all," conditions =""> ["user_id = ?", session[:user].id])
end

def show
@friend = Friend.find(params[:id])
unless @friend.user_id == session[:user].id
flash[:error] = "That friend does not exist"
redirect_to :action => :list
end
end
end

In list, you want to make sure that the list of friends returned belongs to the user, and that's why you find all by the user_id. In show, a user can easily change the URL's id number to reflect another record. You want to check whether that friend actually belongs to them.

While this is all good and well, the problem is, you'd have to do this for every method that you write. We are a lazy kind, so there HAS to be a better way.

Scope it, my brotha from anotha motha

Of course, the Rails geniuses have come up with with_scope() for all ActionControllers.
class FriendController < find =""> { :conditions => ["user_id = ?", session[:user].id] }) do
@friends = Friend.find(:all)
end
end

def show
Friend.with_scope(:find => { :conditions => ["user_id = ?", session[:user].id] }) do
@friend = Friend.find(params[:id])
end
if @friend.nil?
flash[:error] = "That friend does not exist"
redirect_to :action => :list
end
end
end

"But hold on, there's still duplication!" This is only part of the solution. with_scope() is useful if you have multiple database finds within the same block. That way you don't need to keep putting it in the conditions. So how do you get rid of the duplications? With filters, of course.

Add a sprinkle of filter magic

I personally liken filters to programming 'common sense' into the classes. It's what's intuitively understood to have to be done before and after every action. Luckily, there's a filter called around_filter that we can use.
class FriendController < find =""> { :conditions => ["user_id = ?", session[:user].id] }) do
yield
end
end

def list
@friends = Friend.find(:all)
end

def show
@friend = Friend.find(params[:id])
if @friend.nil?
flash[:error] = "That friend does not exist"
redirect_to :action => :list
end
end
end

So it should be pretty obvious what happened. The around_filter allows you to do one responsibility, both before and after every action in the controller. When the method yields, it gives control to one of the actions below. So you're essentially wrapping every action in the with_scope() defined in the filter.

Yay, that's pretty cool. The code's been DRY'd. We're done, right? But you know as well as I, that because there's more text after this sentence, we can actually take it a step further.

I pull out the method inside, served it and fried

Of course, you have more than one ActiveRecord model that's owned by the user, and in this case, there's another one called Post. So instead of repeating ownership_filter method in every ActiveRecord Object, let's pull it out of FriendController into a class of its own, so that other controllers can use it, using some easy meta programming. Note that you now have a require up top and around filter changed.
require 'ownership_filter'

class FriendController < friends =" Friend.find(:all)" friend =" Friend.find(params[:id])" action =""> :list
end
end
end

And this is where we extracted the method to...a file named "ownership_filter.rb" You can put this in your app/controller directory.
class OwnershipFilter
def filter(controller)
model_class_name = controller.controller_name.capitalize.to_sym # => :Friend
model_class = Object.const_get(model_class_name) # => Friend class
model_class.with_scope(:find => { :conditions => ["account_id = ?", controller.session[:user].id] }) do
yield
end
end
end

It actually took me a while to find out how to do this. I knew you could call methods dynamically with send(), but how do you dynamically get a class? Good thing for posts on ruby-talk. So basically, you take the controller's name and you turn it into a symbol :Friend that is used to find the class, using const_get(), that the constant :Friend refers to, namely, the Friend class.

After that, it's the same as before, you call with_scope() with it. So now, you can use this with any of the controllers that you have in the same ways as you did with the friend controller. I haven't tried it yet with the finds pushed down to the ActiveRecords, but I think it should work the same way. Tip!

Update: I saw that the method I described above is actually an anti-pattern according to Jamis Buck. I've posted subsequently on this topic.

Monday, March 05, 2007

Overriding Time.now for Rails testing

When testing in Rails or otherwise, there are times when you need to test time-sensitive, or time-related methods. Before today, I had a hard time finding a good solution to that.

Let's say that you are a person that loves your friends, and the more time that passes, the more you adore them. You'd want to test the love you give a friend grows over time. So you might have something like this:
class Friend
def love
Time.now - @when_first_met
end
end

def test_love_grows_over_time
friend = friends(:jon_lee)
love_now = friend.love

# do something here to shift time forward
# so that Time.now gives a time in the future

love_later = friend.love
assert love_later > love_now
end

A tip here from Rails Studio inserts a wrapper class around Time, and then proceeds to use their wrapper class MyTime in the rest of their application. This is certainly easier to write, but not always possible. There could be methods that uses Time.now in it that you don't want to rewrite (read: don't want to mess with) in a library that you need to use in the tests of your application. And would you really want to replace all instances of Time.now in every library that you use? Search and Replace!

In Ruby, all classes are open, and you can dynamically add methods to both objects and classes. This means that the importance of the wrappers is rather diminished--unless you don't like the idea of a class being open. Because of this example and others, I'm more convinced that design patterns are signs of weaknesses in a language.

So! I know that in Ruby, you should be able to somehow dynamically override Time.now, in order to run friend.love again. You could override Time.now completely, but accordingly, that messes up times in the Unit testing, so tests look like they end before they begin.

In my searches on google, I happen to come across this thread on Ruby talk, which in turn, had a post to Jim Weiriches's OSCON 2005 slide:

def test_warmer
Warmer.use_class(:Heater, MockHeater) do
# Here, anytime a method in Warmer references Heater
# it will get a MockHeater class instead.
end
# Here Warmer is back to normal.
end

Wow, this is pretty neat. What use_class does, is allow you to create a scope where the Heater class is replaced by MockHeater! All classes still use Heater, but Heater is actually replaced with MockHeater within this scope. When the code execute goes back outside of the block, Heater is returned to the original Heater, and not the MockHeater. He achieves this by using a class proxy. You can see the code here.

This is pretty much what I need, so that I'd be able to replace Time with a MockTime. However, as it was written, it doesn't work with Time.now, since now() is a class method. With the way it was implemented, the ClassProxy does not know anything about an object's class methods.

I originally was messing around for hours on how to dynamically add class methods, but I'll spare you the details. What ended up being way easier was just to use method_missing() and pass on any method ClassProxy doesn't know what to do with to the proxied class. So you end up with an extra private method.
class ClassProxy
attr_accessor :proxied_class

def initialize(default_class)
@proxied_class = default_class
end

def new(*args, &block)
@proxied_class.new(*args, &block)
end

private
def method_missing(method_sym, *args)
@proxied_class.send(method_sym, *args)
end
end

So now, you should be able to do this in your test:
class MockTime
def self.now
Time.now.in 2.days
end
end

def test_love_grows_over_time
friend = friends(:jon_lee)
love_now = friend.love

Friend.use_class(:Time, MockTime) do
love_later = friend.love
assert love_later > love_now
end
end

And it should pass! Tip!