RVM Ruby19 and CPL Mail

Feb 18 2010

My main focus for copypastel has been creating a toolset and code standards for all of our applications. This encompasses everything from user account access to coding style. Once complete copypastel will have a solid foundation to build our code upon. If you are serious about creating/deploying products, you need to invest in your own toolset. It’s great to use little snippets of code to cobble together a product (I use this method frequently for proof of concepts) but in the end you are going to need to understand thoroughly each tool in your toolset. The problems will occur when you switch to the real world and start having unexpected bugs. If you didn’t take the time to understand most of the code in the project, you are going to have several nightmarish days as you delve deep to the inner workings of each script you decided to mix together. With a few select tools that you know well it is much easier to figure out where the problem is occurring, and remember, it is the problems you will have to fix in 6 months which will make you cry ;). It is better to have a few master tools as opposed to a toolbox full of scrap.

I would suggest the development of standards with your own team. Though not a novel idea, it really helps when maintaining projects through time. If you find a useful snippet of code don’t just throw it into your toolbox. It may be necessary re-write the script keeping the spirit of its functionality in mind to better integrate it into your toolkit framework. Depending on the situation you may be able to simply write a wrapper API. The goal is to have a framework which allows someone months down the line to modify the code without having to figure out how each extension works. As you read your source code you want to feel like it all comes from the same origin. To better clarify, whenever we have some class which implements a find feature we specify that it must implement ActiveModel. This philosophy comes directly from Ruby’s core. It has several mix-ins which require one definition but then implement several standard access and modify methods. Comparable, and Enumerable are two examples. This enables the developers to easily add functionality with out spending a bunch of time figuring out how the access methods work for that class. Keep in mind that someone on the team should have in depth knowledge of how that class works. It also allows you to leverage Ruby’s duck typing. Ecin spends a great deal of time coming up with appropriate method names for each class he writes, but makes sure to use standard naming conventions for standard functionality. Otherwise, your code will become a maintenance headache.

RVM

To get started on your toolset I would recommend making the switch to ruby 1.9.1 now. It has so many awesome features, and any investment in code you do now will end up getting maintained long after all of your toolset support has left the 1.8.7 world. To make the switch I would highly recommend RVM. I thought I could write a post about it, but it turns out it is so awesome that all you need is the installation link. RVM just works. I was completely blown away. Nothing like this EVER works first time around! rvm install 1.9.1 and you have ruby 1.9.1. rvm 1.9.1 and every ruby command uses ruby 1.9.1! It keeps track of it per shell instance so you can have a 1.8.7 shell and a 1.9.1 shell side by side! I instantly removed my local copy of ruby 1.8.7 and let rvm handle it. The only caveat I had was for autotest. Autotest, for some reason, uses a direct path to the ruby exe; i.e. /System/Libray/Framework blah blah blah (on a mac). Change the shebang (#!) to /usr/bin/env ruby <opts>. On some versions of Unix this may not work because the shebang will try to run "ruby <opts>" as one string, but for most implementations this is a great method for universal ruby scripts.

sqlite3-ruby, or “how I wasted hours migrating”

Another reason to switch to 1.9.1: it’s sort of a pain to get everything working right, so change now! I can’t really explain why, it seems really straight forward after you get everything set; gem install x, gem install y. While trying to migrate however it took me several hours to get things working right, and I didn’t have to change an ounce of code in any libraries. For instance, I installed the sqlite gem instead of sqlite3-ruby. After realizing my mistake I installed sqlite3 and it would boot up, but for some reason one of its methods was missing. Eventually I removed all of the sqlite gems and started from scratch and got things working. There are just some things in server setup that take time to get everything oiled right!

“Take the time to learn your tools”, an anecdote

The last thing I spent a significant amount of time on was Sinatra. This is one of those master tools that should be in your toolkit. Understand how it works and why things happen! I was installing the respond_to gem and unfortunately had some trouble. After four hours of work I came up with this. A complete waste of time, but a mentality that every programmer should have. Just because you can work around a bug in a library doesn’t mean you should. In fact, the only time you should ever write a work around is when you know exactly why the library is causing that behavior, and when you tell the community about it they add it to their bug tracker. Otherwise you are not using the library correctly! From reading the tests it was obvious I could get it working post haste by extending my app from Sinatra::Base. Instead I spent my time figuring out why the classic case did not work. Even worse, the Signature Rdoc does not match up with the current gem release.

My proof is as follows. My first attempt was to use Sinatra.register. I assumed they didn’t extend class methods on object anymore. The code for Sinatra.register in the RDoc was:

            def Sinatra.register
              Application.register(*extensions, &block)
            end
          

The fix is to use Sinatra::Application.register which according to the RDoc is synonymous for Sinatra.register. Going through the code I noticed Sinatra::Default was getting passed to the register method in respond_to. There is a note that Default = Application is deprecated, but clearly the RDoc code lies!

“But why!”, you may ask, is it worth all that time figuring this stuff out? “Aha”, I say. Armed with this knowledge I now use Sinatra::Application.set instead of just set, Sinatra::Application.before instead of just before, and so on in my classic cases. You will notice that if you had a before block it actually was not working. Though some functionality still works they obviously are changing the structure going forward, and it’s best to be prepared! What makes Sinatra so nice is that you could just include the file and be off and running, it is a master tool meant for quick development, but is also able to host a production quality project. You just need to make sure you buff out the burrs in your toolkit every now and then. I would actually recommend you use the extending method, class MyApp < Sinatra::Base for now until they settle on whatever internals are causing things to fail.

Going forward

I have been working on an electronics company for the past year. I use Ruby a lot for all of my server-side scripting. I even use it as a pre-pre-processor for my builds which is extremely useful when mixing Assembly and C programs. Along with that I have had many vaporware projects. One such project is copypastel _mail. We are looking for some beta testers. Ecin has allowed me to put out the request granted that I am actually to the point of using beta testers in 30 days. If I do not then I can never write about my vaporware again ;). It would be a shame because I do have several awesome projects that I hope will see the light of day. So from today I have 30 days, and with this hard date I will see it through.

Copypastel _mail is an API for sending snail mail. There are services out there that allow you to keep track of birthdays, anniversaries, or other important dates and send out little cards for customer relations. It’s a pain because I have not found one of these sites which integrates into your systems, you have to manually upload a CSV, or even type in names manually. Copypastel mail is purely an API for sending the snail mail so you can manage your customer contacts yourself! Just send the text and the address you want it sent to and off it goes. If you are interested please send an email to betamail@copypastel.com and if space is available we will send you an API key.