Monday, June 25, 2007

Getting MySql Working Again with Rails

Over the last few days, and for no reason that I could identify, Rails started throwing numerous connection errors (on Mac OS X). This was quite frustrating, since I could not identify anything that had changed. Nevertheless, I opted to try to upgrade the Mysql driver to see if that would do the trick ( it had in the past).

The first thing I did was upgrade Mysql to 5.0.41 from 5.0.14 or so. Easy peasy. Next, I upgraded the sql driver -

sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config

So far so good. So I kick off mongrel.....and BAM - get a string of errors, including 

dyld: Library not loaded: /usr/local/mysql/lib/mysql/libmysqlclient.15.dylib

After much googling, and not a little telling the ether what I thought of the whole matter, I found a solution:

sudo install_name_tool -change /usr/local/mysql/lib/mysql/libmysqlclient.15.dylib
/usr/local/mysql/lib/libmysqlclient.15.dylib /usr/local/lib/ruby/gems/1.8/gems/mysql-2.7/lib/mysql.bundle


After this, no problems - and most importantly, the intermittent connection errors have stopped.

Tuesday, May 15, 2007

Awk and Textmate - search and replace for LARGE files

Textmate is great, but it tends to choke when you do a search / replace operation on really large files. When it does not choke, it just takes a REALLY long time. Awk to the rescue.

A common task (at least for me) is to update all the fields of a certain type in Rails fixture file. We have one for vehicle records that has around 1500 records, each averaging around 46 lines, for a total file length of around 69K lines. I tried replacing one field for each record (using a regex) in this file, and Textmate ground to a halt.

Enter awk. Using Textmate's Filter Through Command, I performed the operation with one awk command. It took 3 seconds to complete.

Here's how:
1) open the file to be processed in Textmate
2) Hit Command-Option R to invoke Filter Through Command...
3) Enter your awk command, WITHOUT the filename. Mine was

awk '{ sub(/towed_at_date:.*/,"towed_at_date: <%= Date.today %>"); print }' 


4) Select Input: Document, and Output: Replace Document in the dialog box
5) Hit execute.

Friday, February 23, 2007

Just once...

wouldn't it be nice if things just worked the first time?
So I decide to install Trac on Ubuntu. First time installing Ubuntu, but lo and behold, it just installed and worked. So far, so good.

Then its time to install Trac. Good looking instructions. Looks like a no-brainer, which is good, because I am not in the mood for a 10 hour poking-around-all-over-the-damn-internet-looking-for-the-magic-missing-driver crap that I have had to do in the past with Linux. (I love linux, but you have to admit...)

So I issue my first terminal command:

sudo apt-get install trac libapache2-svn

and I get

"E: can't find trac' (not an exact quote, but you get the drift)

The solution was easy (after a google search, of course...), but just once...

Tuesday, January 30, 2007

A Haskell Epiphanette

A link on reddit led me to this:


I think it’s important/useful to point out that “program flow” in a pure functional language is really a matter of data dependency. The compiler is only free to arbitrarily order computations if there are no data dependencies. Furthermore, monads are not special in any way (they are after all just a useful set of combinators; … they only wind up sequencing computations because they set up a data dependency between the two arguments of the bind operator.
-Jeff [bold added by me]

I’m a newbie to Haskell, and like all Haskell newbies, I’m still working through the Monad fog. On the surface, they appeared to me to be not much more than a way to cheat - to write in an imperative style in Haskell. So, I thought, if in the long run all you are really doing in Haskell is writing a bunch of commands, just as you would in C++ or any other imperative language, then what’s the point? Although you could argue that the net result is the same, i.e., you are effectively giving the computer a specific set of instructions to carry out, and in what order (basically), the quote above gave me a new perspective. Sometimes it just takes a little kick…:-)

Friday, January 26, 2007

Rails Routing Errors: The "diff:{}" Problem

Rails error messages are generally pretty good, but like anything, every once in a while you get one that just makes you go nuts. In creating a new section of our application, I decided to go the RESTy route and use the shiny new magic url thingies. To make life even more interesting, I used nested resources. In particular, I set up one route like this:



map.resources :calls,
:path_prefix => 'call_center',
:controller => 'call_center/calls',
:member => { :close => :get } do |call|
call.resources :call_notes,
:controller => 'call_center/call_notes',
:new => {:add_note => :post}
end


Unfortunately, I immediately got this error when I tried to use my new route:



add_note_new_call_note_url failed to generate from
{:action=>"add_note",
:controller=>"call_center/call_notes"},
expected:
{:action=>"add_note",
:controller=>"call_center/call_notes"},
--> diff: {} <--



Notice the last line: diff: {}. So the difference between what the routing system got and what it wanted was….nothing. The answer, which I found after much gnashing of teeth, turned out to be really simple. I needed to add a parameter to the add_note_new_call_note_url. The call that generated the error was




<% remote_form_for :call_note,
:url => add_note_new_call_note_url, ...




What it needed to be was




:url => add_note_new_call_note_url(@call), ...



The @call provides the url generator with the correct context. I had seen (and used) this parameterized url helper in other places, but had not added it here. In fact, I'm still a little fuzzy on when exactly its needed, since some examples (even in AWDWR) don't use it and some do. At any rate, I now have a first place to look when I get this odd error message again. Lesson learned (I hope…)

Sunday, January 21, 2007

Suppressing link_to_if text when condition is false

The rails link_to_if function is great for, well, creating a link if and only if a condition is true. The prototype is


link_to_if(condition,
name,
options = {},
html_options = {},
*parameters_for_method_reference, &block)

Unfortunately, the default behavior is to put the link text on the page (with no link) if the condition is false. To rid yourself of the pesky text, so that nothing shows up if the condition is false, just add an empty block…


link_to_if(false, "Don't show me",a_fancy_url) {}

Bye Quicksilver, for now at least

I was introduced to Quicksilver last year by someone at the Rails user group. I’m not sure how I survived on the Mac without it. I used it for launching apps, appending to files, and jotting quick notes that went straight to kGTD. Incredible productivity booster.


And I just quit using it, and bought LaunchBar. Why? Stability. QS is great, but it crashes frequently - sometimes 5 or 6 times a day. For no apparent reason. Yes, I know its beta. Yes, I know its free. Yes,yes,yes. LaunchBar is more limited, yes, but it is rock solid. And fast. Seemingly faster than QS (although I have not measured it in any way…). If I can find a script that lets me access kGTD from LaunchBar, it may be a permanent replacement. (The only one I’ve found so far seemed to have a problem on the download page)


UPDATE: ..not that anybody but me really cares... :-)
Going to stick with LaunchBar. No crashes, fast, and the advanced kgtd script works with the new version of LaunchBar as easily as it did with quicksilver.

Friday, January 19, 2007

Accidentally accessing accessors in Ruby

I spent about 30 minutes today trying to determine if I had been misunderstanding basic Ruby syntax for more than a year, or if I had just discovered an undocumented bug in the language. The answer was neither, of course.


Ruby variable naming is straightforward. Class instance variables begin with @, as in @user_name. Local variables are unadorned - just user_name. So, when I came across some code that a co-worker had written that did not follow this convention, and he said that it was working fine, I was initially confused. Here’s an extremely simplified example:




1 class VarTest
2 attr_accessor :instance_var
3
4 def print_it
5 puts "The instance var is #{instance_var}"
6 end
7
8 end
9
10 vt = VarTest.new
11 vt.instance_var = "fred"
12 vt.print_it
13


This code should be spitting out something about the invalid use of the instance variable instance_var, right? That should be @instance_var in that method (line 5). But there it was, working just fine.


So I experimented a bit.




1 class VarTest
2 @instance_var = "some initial value"
3
4 def print_it
5 puts "The instance var is #{instance_var}"
6 end
7
8 end
9
10 vt = VarTest.new
11 vt.print_it
12
13 # ~> -:5:in `print_it': undefined local variable or method `instance_var' for #<VarTest:0x1d4558> (NameError)
14 # ~> from -:11
15


Now that’s what I had expected the first time. After more moments of confusion than I really care to admit, the extremely obvious answer came to me. In the first example, instance_var was the accessor method, NOT the variable. Duh. In the second example, where the error was thrown, instance_var was a local variable, since no accessor had been declared. Hence, the error. Again, duh.


It does bring up an interesting point, however. When I am accessing an instance variable from within a method, I use @varname, never just varname. But, I also frequently create accessor methods in Rails models that manipulate the data in some way. This leads to the possibility of some interesting bugs. Here’s a pretty contrived example.




1 class User
2
3 def lastname=(val)
4 @lastname = val
5 end
6
7 def lastname
8 "Mr. " + @lastname
9 end
10
11 def print_name
12 puts "print_name: #{lastname}"
13 end
14
15 def print_name2
16 puts "print_name2: #{@lastname}"
17 end
18
19 end
20
21 vt = User.new
22 vt.lastname = "Kruger"
23 vt.print_name
24 vt.print_name2
25
26 # >> print_name: Mr. Kruger
27 # >> print_name2: Kruger
28


This is fine, and correct of course, unless what I really wanted was “Mr. Kruger” in both cases.



The lesson here is…


The only real lesson is to be aware of the difference between using @ and not in class methods. Best practice is probably to consistently use @, in part simply because it helps differentiate between local and instance variables. In cases where the accessor really needs to be used, as when the accessor function is performing some sort of processing, its best to use self.varname to make it clear that a function is being called.

Monday, January 1, 2007

New blog

Just moved this from the free wordpress.com account, since it lets me change the CSS without paying a fee :-). The entry Evolution:: (Rails,Ruby) -> Haskell appeared on the wordpress site initially, and was refd on reddit. The version here has some updates based on feedback from some folks.