« August 2006 | Main | October 2006 »
September 10, 2006
learns_to Modules and Namespaces: Lessons from Wrapping the del.icio.us api
Last night, I started working on putting together a Ruby-wrapper for the del.icio.us api. I need it to execute this little idea I had recently (more about that when it's done) and I was surprised to find that there wasn't anything too useful out there -- though it's probably because the api is so easy to use you barely need a wrapper around it for most projects. There were a few libraries, but nothing really clean and complete and nothing using the new v1 of the api.
Anyway, in the course of working on the wrapper, I came across a common problem: the need for multiple namespaces. In the api, method names are not unique across objects. For example, there's a method that gets posts for a user and one that gets tags, both called "get" (api.del.icio.us/v1/posts/get and api.del.icio.us/v1/tags/get, respectively). Obviously, those urls leave no confusion as to which "get" method gets which type of object. The question is: what device in ruby should I use to capture this with equivalent clarity?
Two strategies occurred to me immediately: modules and subclassing. According to the relevant section of Programming Ruby, "modules are a way of grouping together methods, classes, and constants. . .[They] provide a namespace and prevent name clashes." Well, that sounds like exactly what I want to do. I want to group together the api methods for posts so that they don't pollute the namesapce for tags. Under this design, I would have multiple modules within my main class, one with the methods for each api "object," posts, tags, bundles, and whatnot.
So, to see if this would actually work, I ginned up a simple example of using modules inside a class. This is what it looked like:
#namespaced class methods
class Test
module Gar
def self.to_s
puts "gar!"
end
end
module Bax
def self.to_s
puts "bax!"
end
end
end
Test::Gar.to_s
Test::Bax.to_s
If you ruby this you'll see this output:
gar!
bax!
In other words, it seems to work for class methods.
But what about instance methods. I made my toy example a little more complicated:
class Best
attr_accessor :dog
def initialize
@dog = "bot!"
end
module Gar
def self.set_dog
@dog = "gar!"
end
end
module Bax
def self.set_dog
@dog = "bax!"
end
end
end
t = Best.new
puts t.dog
Best::Gar.set_dog
puts t.dog
Best::Bax.set_dog
puts t.dog
Unfortunately, this doesn't seem to work. The modules can't get access to the instance variable, @dog. The output ends up looking like this:
bot!
bot!
bot!
This means that I'm thrown back to trying to solve the problem with regular subclassing. I'll be defining a series of classes like this:
class Relicious
attr_accessor :username, :password
#my main class, connects to del.icio.us, etc.
end
class Post < Relicious
def get
#call the posts/get url
end
end
clas Tag < Relicious
def get
#call the tags/get url
end
end
That way, each separate subclass can implement identically-named methods with no danger of namespace confusion. My initial instinct was that this pattern was slightly less elegant than what I was trying to achieve with modules because the subclasses all have to access the centralized connection methods and such in the parent class. The resulting usage code looks like this:
post = Post.new
post.username = "myusername"
post.password = "mypassword"
post.get
which is ugly (a post doesn't really have a username) and inefficient (you'd have to set the username and password attributes fresh if you called Tag.new since you'd have a new instance).
Thankfully, today Chris proposed a better solution, which, in retrospect, should have been obvious to me: wrapping up the child objects inside of accessors in the parent class and then only ever accessing them from there. This would turn the above usage code into this:
rel = Relicious.new
rel.username = "myusername"
rel.password = "mypassword"
posts = rel.posts.get
The namespace problem is solved, everything is meaningfully encapsulated, and the syntax is concise and clear. Sounds like good design. Now, all that's left is to actually implement it. . .
Posted by Greg at 6:19 PM | Comments (2)
September 7, 2006
Bridging the Gap: Socially Responsible Investment Research and Consumer Ethics
In planning the fundraising process for this year's edition of PDX Pop, we came across a problem. With a couple of successful festivals under our belt, we were starting to get through to some bigger sponsors, like Adidas. While this was great for our bottom line -- and the mission it goes to support -- it did raise some concerns amongst our board. How could we ensure that potential sponsors lived up to our organizational values? Or, at the very least, how could we avoid those that egregiously violate them? With Nike in nearby Beaverton, people here are especially conscious of wanting to avoid association with companies of questionable ethical character.
So, I went looking online for some authoritative source on corporate responsibility sure I'd find something. I pictured a site which would give a simple numerical or letter-grade rating to companies on some common ethical concerns: labor conditions, environmental impact, animal testing, etc. The evaluations would be backed by links to hard data.
As you may have already guessed, I didn't find such a site. In fact, I found very little that was truly useful for answering the kinds of concerns our board had raised: some old newspaper reports, a little raw data, a lot of speculation. I started to think that maybe there was no one out there aggregating this kind of information.
I knew there were institutional economic researchers who looked at the masses of hard core financial data these companies generate. And I'd seen some issue-focused ethical watchdog groups that tracked journalistic reports on serious corporate violations of various kinds. But the only people I could think of who would need this type of information in this simplified state for such a broad range of companies would be common consumers. Consumers don't make the caliber of patrons for serious research that investment banks and crusading foundations do. So, I mostly lost hope in such a service ever coming into existence.
Recently, though, I listened to an episode of Social Innovation Conversations that somewhat restored my hope. Expecting Returns: The Role of Socially Responsible Investments and the Market (mp3) was a panel at Stanford's Bridging the Gap conference.
Socially Responsible Investment (or SRI) seeks to combine social criteria into the set of factors traditionally used when evaluating companies for investiture. SRI firms take up the philosophy for a broad variety of reasons ranging from religious taboos on investing in alcohol and gambling through a purely economic desire to maximize profit over a longer time frame. And hence different firms consider different non-traditional factors in picking companies to fund. However, all of these firms have a voracious hunger for accurate and comprehensive data on their potential investment candidates, much of which is outside the range of normal financial indicators used by analysts and much closer to the kind of inputs necessary to make the ethical evaluations that matter to consumers.
In fact, the need for "metrics" was the central theme of the Stanford panel. The moderator, Graham Sinclair, works at KLD Independent Research, a financial research firm specializing in putting together exactly this kind of data and the rest of the panel was made up of managers from different funds, each of which consumes it and generates it continuously. One great example was about one of the managers' investigation of a US oil company operating in post-war Iraq. On first glance, the company seemed to be doing right by local workers and following all the appropriate guidelines. But when the manager called around to local contractors and villagers, he discovered that they were using unfair labor practices and not paying adequate attention to their environmental impact.
Listening to them, it occurred to me that someone might be able to leverage all of this relevant research into exactly the useful customer-facing utility I was looking for to evaluate PDX Pop sponsors. Getting their data out to the public would simultaneously advance the causes these firms care about and raise their own profiles across a broader audience. Also, since the data would by necessity be collapsed into some actionable form for consumer use, the service wouldn't supplant the firms' core business, providing reports to serious investors, which requires comprehension, detail, and personal attention.Whether it happens through the action of SRI firms or not, this kind of data is eventually going to make its way into the public's hands. As Bruce Sterling has pointed out (along with countless others) we are on a timeline of increasing engagement with the products we buy and the companies that make them. We want them to reflect our values and to have meaning to us. In order to achieve these lofty aims, we're going to need to know all kinds of gritty details about the conditions of production and the ethics of corporations. And that means data and lots of it.
Tagged: sri, socially, responsible, investment, stanford, siconversations, innovation, conversations, KLD, research, net-impactPosted by Greg at 1:50 AM | Comments (2)


