Binary Chop Shop in Scala
on November 03, 2009 @ 02:25 AM

In an effort to start learning Scala again (i started in the summer then got busy) I decided to tackle a simple yet fun code kata from Dave Thomas called karate chop

I ended up using Specs to make sure I passed Dave Thomas’s test criteria. I’m sure my below two solutions (recursive and while loop) are quite clunky compared to someone who’s familiar with Scala, but the goal of this was to get something running and passing. In a week or two I’ll revisit again after learning some more things about Scala and hopefully be able to tidy things up a bit.

Anyways, here’s my code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class BinaryChopShop {
  def chopRecursive(target: Int, list: List[Int], args: Int*): Int = {
    if(list.isEmpty) return -1;

    val offset = if(args.isEmpty) 0 else args.first;

    if(list.size == 1){
      return if(list.first == target) offset else -1; 
    } else {
      val index = list.size / 2;
      val value = list(index);
  
      if(target < value)
        return chopRecursive(target, list.slice(0, index), offset);
      else
        return chopRecursive(target, list.slice(index, list.size), offset + index);
    }
  }
  
  def chopWhile(target: Int, list: List[Int]):Int = {
    var nlist = list;
    var offset = 0;

    while(!nlist.isEmpty){
      if(nlist.size == 1){
        return if(nlist.first == target) offset else -1;
      }
      
      val index = nlist.size / 2;
      val value = nlist(index);
      
      if(target == value) return index + offset;
      if(target < value){
        nlist = nlist.slice(0, index);
      } else {
        offset += index
        nlist = nlist.slice(index, nlist.size);
      }
    }
    return -1;
  }  
}

Summary of thoughts on data and migrations
on October 17, 2009 @ 08:16 PM

I shared a summary of my thoughts today with my project team (we’re distributed, multi-national team)... and I thought what the heck why not share with the rest of the world to. Here goes…

I’m not sure what everyone’s conventions or views are on handling the removal of data in the app that is no longer used, so here are some of the guidelines I follow to help promote sharing and consistency.

Seed data

To load data that has to exist for the application to run, I like to use seed data and I am a big fan of Michael Bleigh’s seed-fu plugin. Seed data should be setup so that it can be loaded at any point during the lifetime of an application. It should not destroy data that leaves orphaned data and it should not duplicate data.

Updating data

I like to use migrations to update existing data. If the migration and data update is complex and irreversible I will add a unit test around the migration because due to the high risk of causing irreversible damage (unless a full DB backup is loaded).

Updating application-required data

When the data that the application depends on changes (ie; the seed data) I tend to update both the seed files as well as add a migration to properly handle any existing data, whether this means removing the data, marking it as delete or inactive, etc.

Updating data

In development modifying data directly through MySQL or ruby scripts is much more forgivable and often very fast and efficient. We have no risk of causing users of the application harm or loss of data. Once something is figured out I like to either add a seed-file and/or a migration if it’s a change that needs to get made on staging and production.

In staging modifying data directly is less appealing because staging is supposed to represent what happens when we go to production. If we have to modify data directly in staging then we’ll probably have to modify it in production, so a migration and/or seed-file is a better place to track the change. I find it tempting sometimes to script/console and modify data directly.

A problem with this is that we risk screwing up staging for folks who are using it to preview features, check out bug fixes, etc. I find it better to dump the database and pull it over to my local development machine. Once I have it I can load it up locally, recreate the issue, and do whatever I need to do to find the source of the issue. This removes the risk that you fill further break staging for any users using it. Once I find the issue if I need to I will add/update a migration and/or seed file.

In production modifying data directly is super dangerous. It’s a change that occurs outside of version control and potentially without being run in development and/or staging which could catch bugs in the updates. The risk of causing irrevocable damage is so high I think doing this should be avoided.

I find it’s always been better to take an extra few minutes to make sure the fix is right and then to deploy, then it is to make a quick fix directly in production and find the change caused new issues. Production should never turn into a debugging sandbox. Pulling over a backup if necessary is safer and allows us developers more freedom to freely change the data to find the appropriate fix.

If you have to use script/console not MySQL

If you find you need to update data directly it’s better to use script/console, then by touching the database directly using MySQL. For example, Scott once asked me to change his user name. Changing his user name was a very low risk change, so I loaded up script/console and made it.

The benefit of script/console is that you let all of the rules and validations inside the application be run when you make the change. If I had made Scott’s username too short, too long, include inadmissable characters I would not find out if I did it directly through MySQL, unless I had duplicated all of the logic in MySQL stored procedures and triggers (which I cringe at the thought of).

Conclusion

Well, that’s pretty much a summary of my personal guidelines when it comes to dealing with data updates, migrations, seed-files, etc. If you have any other guidelines you follow that you find helpful please share. I think being on the same page here will help us as we push forward.

git review
on October 01, 2009 @ 01:15 AM

I’ve gotten into the habit of review code that comes down from every other developer, rather than blindly merging in. For a while I was typing “git log master..origin/master” but it became to tedious to type out. I’ve updated my .gitconfig to provide the following alias:

[alias]
  review = !"git log  master..origin/master" 

Now I can simply say:

git review

If you want to view actual code changes rather than simply the changelog just add the -p flag:

git review -p

A little nicer.

BDD not so much, really? Part II
on May 28, 2009 @ 07:38 AM

I think there’s a confusion that BDD == toolset (ie. Cucumber, Cucumber+RSpec, rspec). That needs to stop. BDD is an approach to software development. You drive your software by focusing on behaviour. This is usually done by focusing on behaviour from the outside-in. This starts by identifying the behaviour of the application, then driving inward until you get down to the low level components.

Focusing on behaviour may yield different tools throughout the process. Cucumber and RSpec are just two examples. You could very well use Cucumber plus test/unit, or perhaps just RSpec, or maybe nothing at all. These are just tools to support a development style. They are NOT the development style themselves. You can use Cucumber in a way that doesn’t support BDD. Same goes for RSpec and any other tool.

I realize there are people who don’t buy into the RSpec philosophy. To them it’s just another take on unit testing. I do buy into RSpec. From day one RSpec’s goal has been to be a BDD tool that tries to get the words right. Can you use xUnit libraries in a way to achieve the same affect? Yes you can, but most of those usages have been heavily influenced by RSpec which was built on the ideas and motivation for BDD and “getting the words right”.

Without this focus many of the high level test/unit style add-ons (especially in the ruby world like context, shoulda, test/spec, etc.) wouldn’t exist. So to me, this makes the subtle differences very important as it changed how everyone wrote their tests.

For me personally, testing is an activity after you write code. I find it refreshing to talk about writing code examples to drive design and tests to talk about actual testing. Perhaps it could be phrased as, you start with examples and when you’re done you end up with tests. Similar to starting with user stories and ending up with features. Right now that works in my head, but it’s late and I may need to revisit that thought after a few hours of sleep.

Example is just a better word then test to. When you talk to someone and you don’t understand what they’re talking about you don’t say, “give me a test”, you say, “give me an example”. Well, that language is more natural. You are providing an example of how something should work. This example ends up providing regression (test) value once its implemented, but you didn’t start with a test, you started with an example of the code you wanted.

BDD not so much, really?
on May 28, 2009 @ 06:05 AM

Updated May 29, 2009

This rant is in response to http://robertlally.com/post/bdd-not-so-much

BDD didn’t start off as a replacement for TDD. It started off a way to better understand and explain the process of TDD. The name change as I understand it was to communicate the intent of TDD in a clearer and more direct way. You’re not writing tests for the sake of writing tests, you’re driving behaviour. Focus on the behaviour you want to achieve first and foremost. Use that behaviour as the driving force for your examples (or tests).

Corey Haines nailed it on his comment to the same post, “BDD is no longer a replacement for TDD, but, rather it is a workflow for creating a system that more closely resembles what the client is looking for.” I think two of best tools which exist to support the BDD workflow of outside-in are Cucumber and RSpec. Cucumber for higher level system behaviour and RSpec for driving lower level design.

In the article, the author criticizes the “should” language. Rather than simply scoffing at the idea of replacing “assert” with “should”, I tend to think about it in terms of natural communication. The reason I like “should” language over “assert” language is that when I’m communicating with another developer I don’t say, “assert equal one day to do things good”. That doesn’t make any sense. I say, “one day to do things to should be good”. It’s much more natural for me to write closer to the language I think and communicate than it is to translate it to assertion-speak. I want to communicate in my code more closely to how I communicate to other people.

While the term BDD is a few years old it takes a while for dialogue to happen, and understanding to occur. I’m sure a lot of people hear about BDD, read about it from Dan North’s Introducing BDD . BDD started as a way to explain and better understand BDD, but what I think was realized was that it was much more than simply TDD.

Many tools are emerging which claim to support BDD-style development. It’s important to note that BDD isn’t the tool. You can have many tools support BDD style development in different ways and to different degrees. Although a good tools makes any process easier, what makes BDD is the mindset you have and how you go about writing software. Certain tools emerged with this in mind and are thus labeled BDD tools. Cucumber, RSpec, and JBehave are some examples.

The article mistakingly sheds Cucumber in the light of solely driving the design of code and suggests its a bad tool to do that. Of course it is! It is not a tool intended to drive the design of your code from a low level. It is to communicate in plain text how the application should behave. The plain text is something that is business readable, something that adds value not at the code design level, but at a higher level: communication and understanding requirements!

Cucumber is equivalent to a high level integration test for those of you who come from a testing background. It runs the entire application (or whatever can be reached through automation, different types of systems have different limitations). It works in combination with a tool used to drive out the design of your application using lower level code examples. For example, RSpec.

The #1 output of BDD is a working application that is behaving as expected. In addition to that you have an application-level regression suite in which you can run against the code base at any time. You also end up with smaller, more focused code examples which provide regression against isolated behaviour of the system.

Combined, you end up with documentation at two critical aspects. The first is business readable scenarios that the system supports. The second is developer documentation made up of the lower level code examples. Since these are often written more clearly than assert-style syntax it’s easy to produce human readable behaviour specifications for focused pieces of behaviour. And in the end you have a repeatable process which allows you to confidently produce the working software.

I also don’t see where UML to BDD comparisons make any sense. UML is a modeling language. BDD is more of an approach or methodology. A more accurate comparison would be plain text scenarios vs. UML. Although that makes little sense as a comparison because UML is not something you can give a non technical person to write, read, and edit.

BDD by itself doesn’t fix any problems. It provides an approach which focuses on behaviour first. To me, there’s no point in building a low level library if you’re not aware what higher level problem you’re solving or objective you’re adding value to. This boils down to a person still has to “do the work” to make it successful.

At the end of the day though I cannot speak for anyone else except myself. Shifting my focus on behaviour rather than “tests” led me to write better code examples. Often times I would write less of these because I was writing better examples. It’s also helped improve communication between myself and my team, customers, and other developers. BDD may evolve into something else, or perhaps a new perspective will come around that will take the world by storm. I am all about continuous learning and improvement. And I invite any ideas Mr. Lally or anyone else brings to the table.

Also, BDD never claimed to be THE answer. Any process that claims to be THE answer will surely not be THE answer for everyone in all situations. BDD has been an answer for many people though and as of now it will continue to be an answer for me in how I work.

A good resource worth checking out for BDD, it’s philosophy, and how to apply it in practice is The RSpec Book

rspec/cucumber ML email etiquette
on May 09, 2009 @ 03:18 AM

Aslak Hellesoy requested on the rspec/cucumber mailing list the other day that folks stop top posting. His words:

I find it really hard to follow conversations that use top posting (http://en.wikipedia.org/wiki/Posting_style). If you have a [Cucumber] topic, please respond with inline comments. And use plain text email – not html.

I agree with Aslak’s request for the most part. There are times when top posting is perfectly acceptable, but those are too often blurred by the countless times where people are just plain lazy. While most of the replies have been rather humorous in response a couple recent replies have the look of actual requests to the community: snip out things not pertaining to your reply and the removal signatures.

The only part I don’t agree with is the text email. I’m sorry, but if you use an email client which can’t show html, or can’t not show the html part of an email then you need to find a new email client. I have the feeling Aslak was referring to folks that only send HTML email, void of a plain text part. If that’s the case I am in full agreement with his request.

Aslak’s request was well intended and thoughtfully brought about. I hope the replies stop before there is a giant list of dos and donts, followed by a flamewar that will most likely have a negative impact on such a wonderful community.

RSpactor, love Cucumber
on April 28, 2009 @ 10:02 AM

If RSpactor loved Cucumber it’d be even more amazing. From the ticket request:

It would be amazing if RSpactor integrated with Cucumber although 
it would need to be a different than how it currently works with 
RSpec. Now that Cucumber has tag support I think this good be done 
in a reasonable way that improved the developer workflow for 
projects that utilized Cucumber.

Here's an example. When I am working on changing how money is 
managed in my app I know that I want to run the features tagged 
@accounting. At the start of my work it'd be great if I could 
add the @accounting tag to RSpactor so it would run those 
features after it successfully ran specs. 

Perhaps there would also be a preference setting which auto 
ran the Cucumber scenarios after specs ran, or one that forced 
you to manually hit play. Although if you had typed in tags, 
it the play button would run cucumber with those tags. 

Got a better idea for Cucumber integration? Join the discussion! http://github.com/rubyphunk/rspactor/issues/#issue/1

Managing Client Expectations
on April 08, 2009 @ 01:15 AM

Managing client expectations is simple, but like most things simple—it’s very hard to do, do right, and do consistently. I think this is a common problem in today’s web development companies. The industry has a lot of young, creative, and smart people building companies with little to no experience in customer relations. For every person who is naturally gifted or good at managing client expectations there are probably several more people who just don’t get it. And the worst part, is that they probably aren’t aware of the fact that they don’t get it.

I’m one of those young, creative, and somewhat smart people in the industry trying to build a company in the web industry, but this is an issue that has been nagging me for months, and it’s to the point where I feel like it needs to be shouted from the mountain tops (although this blog is probably more like a anthill). It may not be the best business decision on my part since it encourages competing companies to become better. If they do it will make us humans work that much harder.

I’m sorry to say it, but few web development companies seem to do a good job of development and a good job of managing client expectations. Maybe your company is good at development, but stinks at managing client expectations. Or maybe it’s the other way around and you are great with the customer, but your team is a bunch of junior developers who crank out crap. Oddly enough, if your company falls into the latter you have a much better chance of being successful and surviving than the former.

Before look at some of the effects of managing (and failing to manage) client expectations let’s start with a simple definition:

Managing client expectations is the ability communicate proactively with the client in a reasonable and realistic manner that allows them to take ownership of decisions that may affect their project or business.

Managing client expectations is about communicating honestly, openly, and often with the client. It requires informing them of things that have the potential to impact their business or their project. I use the term proactive in the definition because you’re not doing it right if you do something and than communicate after the fact. Heck, doing that is like this the plumber who came to your house and failed to manage your expectations:

A plumber comes to your house to fix your toilet. At first glance it looks like it’ll take an hour to do so you set aside $100 on the counter to cover the cost and leave so the plumber can work in peace. While working the plumber discovers a much bigger plumbing problem. He’s really in the zone though, so rather than calling you he just does what’s necessary to fix the issue. You get home later in the day, and on the counter you see your $100. Next to it is an invoice for $2,200 and a note that reads: I ran into a bigger problem, but I was really in the zone so I replaced the plumbing in the basement because it would have had to have been done.

Do you feel the plumber did a good job of managing your expectations? Would you hire that plumber back? Would you pay the bill? I would answer three hell nos. Yet, many web developers and young web entrepreneurs find this perfectly acceptable and they wouldn’t think twice about doing it. To them it’s just how you move a project along its merry little way.

For folks who aren’t aware this is a problem—it is a problem and you should stop doing it. For folks who do it and know they do it, wake up, its unhealthy for your client, you, and your business.

I think it’s universal knowledge that finding a new client is more costly then keeping a client. Every time you interact with a client you have a chance to increase or decrease your likelihood of keeping them as a client. When you manage their expectations well you will most likely keep them. Here are three general reasons why:

  • build a healthy relationship
  • build trust
  • empower the client, giving them ownership

Positive effects of managing client expectations

Build a healthy relationship

Every time you interact with a client you have the ability to build a slightly better relationship. Setting clear expectations with the client with good solid communication strengthens the bond between you and your customer. Customers who have a healthy relationship w/their suppliers are not likely to jump ship.

A new developer joins your team. Every time you work with him you notice he takes the time do things right rather than just quick. He also seem to ask questions and raise questions at all the right times. You find yourself comfortable working with him and before you know if you even think that you do better when working with him. When the developer’s 90 day review comes up you’re first to speak up and ask the team to keep him.

Build trust

Part of building a healthy relationship is trust. To me, trust is like trying to level a character in EverQuest. As you build up stats and level you gain a new skill or perhaps a new magic. The higher you level the more your character is capable of. The same is true for the relationship with a client. As you achieve new levels of trust with your client you achieve new capabilities for doing things. Perhaps your client sends you more work. Perhaps your client refers you to his peers and to other companies. Perhaps your client invites you to more business-oriented meetings because he wants you involved in streamlining technical aspects of their business. Perhaps you become the goto shop for your client’s organization. Without trust this is not possible.

A new developer joins your team. After the first few months of working with her you find she is a good, honest, hard working, and capable developer. You build up trust in her as a developer. A potential client comes in and you need to send over a couple developers to help kick off the first Planning Game and do some story estimation. You send her. You know she’ll do a good job, ask questions, and be honest.

Empower the client, giving them ownership

Empowering the client is something that we really need to do a better job of in our industry. Managing a clients expectations lets the client own the decisions that need to be made that impact their project or business. These decisions are not ours to make, they are our clients. When the client owns the decisions, they own the project, they own the direction of the project. This isn’t to say we don’t guide or assist our clients in finding that direction. This is one of the many reasons we are often hired, however, when a client gives you permission to make decisions for them, they made that decision. When that’s not the case and we make decisions for the clients we are simply being lazy and bad vendors.

As a developer who practices Behaviour Driven Development I want my customers to own the scenarios that are written to drive the development of an application. The customer may physically write any of the scenarios. I may type them while sitting with the client, or during a phone call, but I am merely being a scribe. They own the scenarios. I never want the customer to feel that scenarios are written simply to translate business speak to technical speak, I want the customer to own the scenarios so its clear to them what they are paying me to build. Doing this empowers the client, it gives them ownership. They are usually much more engaged in the project when this happens.

Negative effects of failing to manage client expectations

Now, when you don’t manage client expectations you can have the opposite effect:

  • hurt the relationship
  • lose trust
  • empower yourself, taking ownership away from the client
  • increase the risk you negatively impact the clients business

Hurt the relationship

Not managing client expectations hurts the relationship. You may get away with it once, twice, or even three times, but sooner or later you will guess wrong and your customer will be ticked off. This is usually when they start looking for a new vendor.

Your customer has a feature they want added. You estimate 50 hours. It ends up taking you 110 hours. You don’t tell the client, you simply send them a bill. The customer is ticked, he asks that you stop working until the bill can be addressed. He wants to do a phone call with you to dispute the bill. Your customer is not happy.

Lose trust

Losing trust is a part of hurting a relationship, but trust is so important on its own. Most companies want to be a partner with the client. They want the client to leverage their expertise in solving a problem. If we don’t have that kind of relationship we lack the trust required for the customer to to utilize us in that way. Every time we fail to manage a client’s expectations we lose a level of trust. At some point its gone, and we’re out of the picture.

Empower yourself, taking ownership away from the client

Making decisions that affect the client’s project or business are a big no no. It takes ownership away from the client and only empowers yourself, but that empowerment only lasts a short while. You may have won the battle, but you will surely lose the war. First of all, decisions that impact the client’s project or business are theirs to make—not yours. Sometimes an emergency arises, the app is down! Chaos ensues! What to do? One of the very first things you do is call your client and give them the ability to say “no, don’t fix it”. Even though that answer may be highly unlikely, its not your decision to make, unless you have an arrangement with your client to make those decisions. Perhaps you have an agreement which covers what to do in those circumstances. If you do, more power to you. If you don’t, you may want to consider getting one.

Maybe you’re wondering what happens if you can’t reach the client? Do you wait to fix it until they call you back? I would say that depends on the nature of the issue. At minimum you should leave a voicemail and send a quick email, both which have your contact information. Doing this allows you to do everything reasonably possible to contact the client of the issue. And it may add 30 seconds to 2 minutes of overhead. This is usually reasonable. However, this is one of those times where it depends based on the relationship you have with your client. Fixing the issue first and responding later may be acceptable based on your arrangement. My belief is that if that’s not your arrangement than you should be contacting your client. Well, you should be contacting them anyways—that’s just being a good vendor.

The client’s site goes down. You get a call from one of their programmers (not a decision maker or gold owner) about it. You log in, evaluate, and decide to tackle it. Some time later you get it fixed! Woot! Invigorating, wasn’t it? Then you send a bill to the client. The person who pays the bill and has decision making power for paying the bill is very upset. Why a $1,200 bill? And why wasn’t he made aware of it? He heard from his one of his programmers their was an issue, but that it got resolved, why is the vendor sending a bill?!!

Increase the risk you negatively impact the clients business

Every time you make a reckless decision on behalf of your client without having some kind of prior arrangement or relationship in place you increase the risk that you will negatively impact their project or business. These are risks that are not yours to own, they are your clients. They always deserve the ability to say “no” even if it seems highly unlikely. The only time they shouldn’t have that option is if someone’s physical health is in immediate danger, but I haven’t seen any webapps running medical equipment, handling stop lights, or coordinating the release of water at Hoover Dam.

BDD w/Rails Class
on April 03, 2009 @ 02:30 AM

Shortly after RailsConf and while The RSpec Book is hitting the printers I’m going to be teaching a BDD w/Rails class with the amazing guys at Collective Idea

Hope to see you there!

Scenario Observation
on March 20, 2009 @ 12:00 AM

One of the hardest things about being the developer and the scenario writer is that we’re in the thick of it. Once we get something written down we want to get it to work and then move on. This may involve copy and pasting part of an existing scenario to just get the job done. We get antsy.

One of the benefits of having the customer (or someone else) write the scenario is that we get to be the critic and not the author. We can focus on the scenario and ask questions like: does it read well? Is it doing too much? Is doing little? Can I understand its intent? etc. etc.

When working with a pair our pair should really challenge us to write good, communicating, intention revealing scenarios (just like they should be doing with code). This can be hard when we are working solo because we may just be staring at the screen for too long, and we can’t see the forest for the trees. If that’s the case grab someone else for a quick review, even if it’s after you finish implementing the scenario. Refactoring applies to scenarios to.

Scenarios are like code, if we don’t tend them well, they will grow messy and hard to maintain. We are best served to spend a little time upfront to keep them tidy rather than wait until we have hundreds of steps that don’t do a good job of communicating and require people to have to read through all of the step definitions to figure it out.

Go forth and code! ;)

ar-extensions 0.8.2 released
on March 17, 2009 @ 02:09 AM

ar-extensions 0.8.2 is released. This release fixes compatibility issues with Rails 2.3.1 and Rails 2.3.2. It should show up soon at a rubygems mirror near you.

Thanks to Stephen Heuer, Glenn Rempe, and Michael Murray.


gem install ar-extensions -v 0.8.2

CachingPresenter has moved
on February 14, 2009 @ 11:03 PM

The new home for CachingPresenter is: http://github.com/mhs/caching_presenter

What is CachingPresenter?

CachingPresenter is a very small presenter pattern implementation in Ruby. In short, the presenter pattern is a technique used to separate presentation logic (aka display logic or view logic) from domain logic and from the view templates themselves. There are a number of reasons this pattern is beneficial when used:

  • it stops presentation logic from creeping into domain objects and muddying up their implementation and their business logic
  • it stops unnecessary logic from creeping into the views themselves which should be as simple, flexible, and changeable as possible
  • it allows you to organize presentation logic in better ways than simply maintaining helper modules that are included everywhere

CachingPresenter seems to be benefit most web-based projects where there is benefit from a separation between the view templates and corresponding presentation logic. It works superbly with Rails, but it is not dependent on Rails. You can use it for any ruby project, web-based or not.

Recent Changes

:requiring is removed in favor of :accepts

The :requiring option has been removed in favor of :accepts. This allows all additional arguments to be optional. For example:

1
2
3
4
5
6
7
8
9
class NinjaPresenter < CachingPresenter
  presents :ninja, :accepts => [:sword, :agility]
end

# supplying all options
ninja = NinjaPresenter.new :ninja => Ninja.new, :sword => Sword.new, :agility => 100.percent

# supplying only some options, previously this would yell at you for not supplying :agility
ninja = NinjaPresenter.new :ninja => Ninja.new, :sword => Sword.new

Caches hash-reader methods

If a presenter defines the #[] method or if what is being presented on responds to the #[] methods all calls to the presenter using hash-like accessors will successfully be cached. Previously this would die.

1
2
3
4
5
6
7
8
9
10
class SamuraiPresenter < CachingPresenter
  presents :samurai, :accepts => [:stats]

  def [](key)
     @stats[key]
  end
end

samurai = SamuraiPresenter.new :samurai, :stats => { :dexterity => 80.percent }
samurai[:dexterity] # => 80.percent

Does not try to cache writer methods

Usually you don’t use writer methods on presenters, but every now and then there is a good reason. Previously, CachingPresenter would completely fail if you writer to define an writer method, now it doesn’t. And it will successfully not be cached.

1
2
3
4
5
6
7
8
class SamuraiPresenter < CachingPresenter
  presents :samurai, :accepts => [:stats]

   # previously this line would have failed miserably
  def sword=(sword)
  end

end

Questions / Docs / Contact / Etc

Any questions, checkout the github page and its corresponding wiki . If all else fails let me know, zach dot dennis at gmail dot com

0 comments | Filed under: rails ruby | Read on...

ar-extensions 0.8.1 released
on February 10, 2009 @ 01:15 AM

ar-extensions 0.8.1 is released. This is primarily a bug fix release to ensure it works successfully with Rails 2.2.2. Here are the changes:

  • fixed issue in http://zdennis.lighthouseapp.com/projects/14379/tickets/14-join-table-conditions-broken
  • Updated usage of Inflector to point to ActiveSupport::Inflector
  • Fixed bug where finder conditions which use arext-suffixed keys and normal field keys would fail when using a conditions hash. (Gabe da Silveira)
  • added timestamps options to not automatically add timestamps even if record timestamps is disabled in ActiveRecord::Base (Thibaud Guillaume-Gentil)
  • Updated to use alias_method_chain so that multiple aliased finders remain intact (Marcus Crafter)

It may take a little while for the gem to show up in the rubygem mirrors. Thanks to everyone who contributed!

2 comments | Filed under: arext rails ruby | Read on...

Long time, no see
on January 06, 2009 @ 09:13 AM

It’s been a long while since I’ve written. It’s been more due to time constraints than anything. Last spring I joined Mutually Human Software full-time, then in the early summer spoke at RailsConf, and then in the late summer started working on the RSpec Book. 2008 was a very busy year all the while spearheading a project for the state of Nebraska.

I have a lot of rough draft articles I’d like to clean up and push out, as well as finish Annex—the soon-to-be 1.0 release of ar-extensions. In the meantime I am going to be pushing some things out to MHS’s blog like the recent post on Using custom ActiveRecord events/callbacks .

We’ve also just wrapped up the year with finishing a project for one our clients. If you need assistance with an existing project, or are looking to get a new project off the ground, or are interested in training/consulting we do that over at Mutually Human. Our specialty is web applications. Be sure to drop us a line at zdennis at mutuallyhuman dot com.

Stay tuned, this is going to be an eventful Spring both at continuousthinking and MHS,

0 comments | Filed under: life | Read on...

ar-extensions 0.8.0, forgot to mention
on August 16, 2008 @ 02:17 PM

I forgot to mention that ar-extensions no longer loads adapter specific functionality by itself. You need to tell it what you want. For example if you want to load import functionality for MySQL you’d have to require the right files, like so:

1
2
require 'ar-extensions/adapters/mysql'
require 'ar-extensions/import/mysql'

Sorry about that.

1 comment | Filed under: arext rails ruby | Read on...