<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5611656633903981530</id><updated>2011-11-23T18:54:17.927-08:00</updated><category term='ruby'/><category term='windows'/><category term='curb'/><category term='S3'/><category term='curl'/><category term='SWFUpload'/><category term='Rails'/><title type='text'>Begin Rescue</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://beginrescue.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://beginrescue.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>pete higgins</name><uri>http://www.blogger.com/profile/06164347683461976036</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5611656633903981530.post-1600909893511454752</id><published>2010-07-05T20:19:00.000-07:00</published><updated>2010-07-05T21:29:06.559-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='curl'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><category scheme='http://www.blogger.com/atom/ns#' term='curb'/><title type='text'>Installing Curb with Ruby 1.9.1 in Windows</title><content type='html'>&lt;strong&gt;Disclaimer:&lt;/strong&gt; This is about how I installed curb in Windows XP. This is probably not the only way and certainly not the best way. I'm not a Windows developer (I just play one on TV) and haven't done any work with C in an embarrassingly long time. I'll be happy to help with any problems, but please don't expect me to be able to fix this at 5pm on Friday when your production machine decides to blow up.&lt;br /&gt;&lt;br /&gt;Now that we got that out of the way...&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;How I finally got curb to install in Windows.&lt;/strong&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Install the latest &lt;a href="http://rubyinstaller.org/downloads/"&gt;Ruby installer and DevKit&lt;/a&gt;.&lt;/strong&gt;&lt;br /&gt;The finer points of doing that are outside the scope of this post, so if you have trouble with those things I'd reccommend &lt;a href="http://geeksharp.com/2010/01/18/windows-ruby-native-gems-1-9-1/"&gt;this tutorial&lt;/a&gt;, the &lt;a href="http://wiki.github.com/oneclick/rubyinstaller/development-kit"&gt;DevKit Howto&lt;/a&gt; and the excellent &lt;a href="http://groups.google.com/group/rubyinstaller"&gt;RubyInstaller mailing list&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Just for the record, I'm using the latest as of the time I'm writing this: ruby-1.9.1-p429 and devkit-3.4.5r3-20091110.7z.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Get libcurl.&lt;/strong&gt;&lt;br /&gt;I, again, am using the latest as of the time I'm writing this: &lt;a href="http://www.gknw.net/mirror/curl/win32/curl-7.21.0-devel-mingw32.zip"&gt;7.21.0&lt;/a&gt;. If you need a different version for whatever reason, the libcurl downloads page has a few different versions available, so make sure to get the one for mingw32 and that you get libcurl and not plain-old curl.&lt;br /&gt;&lt;br /&gt;With that downloaded, I extracted the .zip file to the root of my C:\ drive. The location you put this is important for the next steps.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Put the curl binaries in your path.&lt;/strong&gt;&lt;br /&gt;My preferred way is to add the libcurl \bin folder to the Windows path, so that typing 'path' at a Windows command prompt gives a result like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;C:\&amp;gt;path&lt;/code&gt;&lt;br /&gt;&lt;code&gt;PATH=C:\Ruby191-p429\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\curl-7.21.0-devel-mingw32\bin;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Other things you can do here are copy the libcurl .dll files into your ruby's \bin folder (or anywhere else in the PATH) but I think that's kinda lame.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Install curb.&lt;/strong&gt;&lt;br /&gt;The magic incantation I found for this was the following:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;gem install curb -- --with-curl-lib=C:\curl-7.21.0-devel-mingw32\bin --with-curl-include=C:\curl-7.21.0-devel-mingw32\include&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Every other combination of flags and paths resulted in compilation errors, so you've been warned. Also, you'll need to change the curl paths if you decided to install to a different place or with a different version.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Test it.&lt;/strong&gt;&lt;br /&gt;Here's a very simple script that will load curb and GET a url:&lt;br /&gt;&lt;code&gt;require 'curb'&lt;br /&gt;&lt;br /&gt;c = Curl::Easy.new&lt;br /&gt;c.url = "http://example.com"&lt;br /&gt;c.http_get&lt;br /&gt;puts c.body_str.size &lt;br /&gt;&lt;br /&gt;# Output:&lt;br /&gt;# 574&lt;/code&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Did this work for you? Let me know in the comments!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5611656633903981530-1600909893511454752?l=beginrescue.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://beginrescue.blogspot.com/feeds/1600909893511454752/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5611656633903981530&amp;postID=1600909893511454752' title='21 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/1600909893511454752'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/1600909893511454752'/><link rel='alternate' type='text/html' href='http://beginrescue.blogspot.com/2010/07/installing-curb-with-ruby-191-in.html' title='Installing Curb with Ruby 1.9.1 in Windows'/><author><name>pete higgins</name><uri>http://www.blogger.com/profile/06164347683461976036</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>21</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5611656633903981530.post-7047195702720072646</id><published>2009-04-21T16:42:00.000-07:00</published><updated>2009-04-27T23:03:46.350-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SWFUpload'/><category scheme='http://www.blogger.com/atom/ns#' term='S3'/><category scheme='http://www.blogger.com/atom/ns#' term='Rails'/><title type='text'>Getting S3 and SWFUpload to Cooperate in Rails</title><content type='html'>&lt;strong&gt;Updated on 4/27:&lt;/strong&gt; Added the workaround for the bug in the Mac's flash plugin.&lt;br /&gt;&lt;br /&gt;(First things first, there is a &lt;a href="http://github.com/elcgit/s3-swf-upload-plugin/tree/master"&gt;rails plugin&lt;/a&gt; that automates a lot of this process. I didn't like the way it worked for a few reasons (like making swfobject.js into &lt;a href="http://github.com/elcgit/s3-swf-upload-plugin/blob/e810b86f113e61abdc84dda790437e3b4c4c1cdc/generators/s3_swf_upload/templates/s3_upload.js"&gt;one big javascript variable&lt;/a&gt;), so I decided not to use it. PJ at GitHub &lt;a href="http://github.com/blog/350-repository-uploads"&gt;mentioned that they use it&lt;/a&gt;, so it must not be all bad.)&lt;br /&gt;&lt;br /&gt;These are some stumbling blocks I ran into and I thought I'd try to save others some frustration. I'll try to link or acknowledge the particular sources where I read these nuggets, but I've been googling like mad the last few days and might have forgotten.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Signature and Policy generation&lt;/strong&gt;&lt;br /&gt;elcgit decided to reinvent some wheels with the &lt;a href="http://github.com/elcgit/s3-swf-upload-plugin/blob/e810b86f113e61abdc84dda790437e3b4c4c1cdc/lib/s3_swf_upload/signature.rb"&gt;signing and policy generation&lt;/a&gt; bit, and wrote his own base64 encoding routines. This is unnecessary, because ruby includes &lt;a href="http://www.ruby-doc.org/stdlib/libdoc/openssl/rdoc/index.html"&gt;openssl&lt;/a&gt; and &lt;a href="http://www.ruby-doc.org/stdlib/libdoc/base64/rdoc/index.html"&gt;base 64 encoding&lt;/a&gt; capabilities in the stdlib. In fact, amazon provides sample code for this on &lt;a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1434"&gt;this helpful documentation page&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;require 'base64'&lt;br /&gt;require 'openssl'&lt;br /&gt;require 'digest/sha1'&lt;br /&gt;&lt;br /&gt;policy = Base64.encode64(policy_document).gsub("\n","")&lt;br /&gt;&lt;br /&gt;signature = Base64.encode64(&lt;br /&gt;   OpenSSL::HMAC.digest(&lt;br /&gt;       OpenSSL::Digest::Digest.new('sha1'),&lt;br /&gt;       aws_secret_key, policy)&lt;br /&gt;   ).gsub("\n","")&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;S3 Post Params&lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;How to pass the &lt;a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?HTTPPOSTForms.html#HTTPPOSTFormFields"&gt;required POST parameters&lt;/a&gt; to S3 with SWFUpload might seem somewhat obvious, but I wasn't sure how to do this in the beginning. You merely need a line like when setting up your SWFUpload object:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;post_params : &lt;%= @s3.to_json %&gt;,&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I made a class to encapsulate all the S3 stuff, created an instance in the controller, and then call the .to_json method (delegated to hash) so that I didn't have to specify all that stuff in the view.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;S3 requires a field called "file" to be present in the POST parameters, but by default Flash (and therefore SWFUpload) name this field something else. You can change this by including this line in your SWFUpload configuration:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;file_post_name : "file",&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;S3 requires all POST parameters to be present in the policy that's signed and passed in the parameters, so make sure to add this line to tell S3 to expect a parameter that SWFUpload provides by default:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;["starts-with", "$Filename", ""]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;To work around &lt;a href="http://swfupload.org/forum/generaldiscussion/1240"&gt;an apparent bug in the Mac's flash plugin&lt;/a&gt;, I had to add the "success_action_status" key to the S3 policy and POST parameters with a value of 201. According to the S3 docs, the default return code of 204 is sent with no response body, which apparently triggers the bug.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;SWFUpload and Return Codes&lt;/strong&gt;&lt;br /&gt;Depending on a few options you specify, S3 can return a 200, 201 or 204 for a successful upload. By default, SWFUpload treats any return code other than 200 as an error. You can fix this on the S3 side by supplying the success_action_status parameter, but I chose to make it so that SWFUpload would regard those three return codes as successes by adding this to my SWFUpload config:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;http_success : [ 200, 201, 204 ],&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Host the SWFUpload File on S3&lt;/strong&gt;&lt;br /&gt;SWFUpload does not have very good support for uploading to a different domain than the actual .swf file is hosted on due to crossdomain issues. I spent a day or two trying to make this work with the proper settings in a crossdomain.xml file, but gave up and decided to host the .swf on S3. This adds a bit of a deployment headache, but it's a much simpler solution (and possibly the only one).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Debug By Uploading to Rails&lt;/strong&gt;&lt;br /&gt;SWFUpload does not provide a lot of debugging help; sure, it has a debug mode which gives some info, but for a lot of server-side things it's not very helpful (I'd have been saved a lot of trouble if SWFUpload would display the response body and not just the return code on a failed upload, for example). You can get a look at the POST parameters being sent if you set SWFUpload's upload_url setting to a dummy action in your app and looking at the logs.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Functional and Acceptance Testing&lt;/strong&gt;&lt;br /&gt;I've recently started using Cucumber for testing and love it. Unfortunately, I wasn't able to get it to work with SWFUpload properly; this led to me essentially "flying blind" with no tests and having to do a lot of testing in the browser (yuck!). If I can find out how to do this (or someone else lets me know), I'll update this entry to have that info.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5611656633903981530-7047195702720072646?l=beginrescue.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://beginrescue.blogspot.com/feeds/7047195702720072646/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5611656633903981530&amp;postID=7047195702720072646' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/7047195702720072646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/7047195702720072646'/><link rel='alternate' type='text/html' href='http://beginrescue.blogspot.com/2009/04/getting-s3-and-swfupload-to-cooperate.html' title='Getting S3 and SWFUpload to Cooperate in Rails'/><author><name>pete higgins</name><uri>http://www.blogger.com/profile/06164347683461976036</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5611656633903981530.post-5241210272390209036</id><published>2008-10-07T10:20:00.000-07:00</published><updated>2008-10-07T10:41:31.896-07:00</updated><title type='text'>Testing for database insert with ActiveRecord</title><content type='html'>Often in my tests, I want to test to see whether a database insert occurred; more often I want to make sure that an insert did &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; happen. I've found a few approaches using mocking, neither of which I was very satisfied with.&lt;br /&gt;&lt;h1&gt;Mocking AR's connection's insert&lt;/h1&gt;&lt;br /&gt;This approach won't win you any code cleanliness awards, but when you absolutely must tell whether or not your code is trying to insert records, this will get the job done.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;def test_that_fails_if_any_inserts_happen&lt;br /&gt; flexmock( ActiveRecord::Base.connection ).should_receive( :insert ).never&lt;br /&gt;&lt;br /&gt; # code to test&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This doesn't make an assertion, but flexmock is setting an expectation that the method insert will never be called on AR's connection object before flexmock's teardown gets called.&lt;br /&gt;&lt;h1&gt;Mocking model's create&lt;/h1&gt;&lt;br /&gt;This is a little higher level, but even more deeply coupled with your code.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;def test_that_some_model_never_creates&lt;br /&gt; flexmock( MyModel ).should_receive( :create, :create! ).never&lt;br /&gt;&lt;br /&gt; # code to test&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Doing the test this way seems a little cleaner at first, but there's one major caveat: create and create! are only two avenues to doing an insert in the database; this test would pass if the code was refactored to make a raw sql insert, if it used &lt;a href="http://continuousthinking.com/tags/arext"&gt;ar-extension's&lt;/a&gt; import method, etc. You could remember to change the test if either of those things were to ever happen, but it's best to just avoid this unless you have few options.&lt;br /&gt;&lt;h1&gt;How does ActiveRecord test this?&lt;/h1&gt;&lt;br /&gt;After being unsatisfied with the last two ways to test this, I got the bright idea to look at AR's tests and see how they test this. Surely they need to test whether objects get created, right? Right. This is taken from AR 2.1.1's finder_test.rb, lines 598-604:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;def test_find_or_create_from_one_attribute&lt;br /&gt; number_of_companies = Company.count&lt;br /&gt; sig38 = Company.find_or_create_by_name("38signals")&lt;br /&gt; assert_equal number_of_companies + 1, Company.count&lt;br /&gt; assert_equal sig38, Company.find_or_create_by_name("38signals")&lt;br /&gt; assert !sig38.new_record?&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;As you can see, to test whether a database record is created, they take the count of the table before and after the code they're testing, and make sure the final count matches their expectation. Simple.&lt;br /&gt;I was a little underwhelmed by their solution. It's clean, but it's lacking something that I can't put my finger on. Overall. I like their way of testing this over my two solutions, so I've started refactoring my tests to work this way.&lt;br /&gt;&lt;br /&gt;Has anyone out there run into this problem, and come up with a better solution?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5611656633903981530-5241210272390209036?l=beginrescue.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://beginrescue.blogspot.com/feeds/5241210272390209036/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5611656633903981530&amp;postID=5241210272390209036' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/5241210272390209036'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/5241210272390209036'/><link rel='alternate' type='text/html' href='http://beginrescue.blogspot.com/2008/10/testing-for-database-insert-with.html' title='Testing for database insert with ActiveRecord'/><author><name>pete higgins</name><uri>http://www.blogger.com/profile/06164347683461976036</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5611656633903981530.post-3947626736312896594</id><published>2008-09-30T00:34:00.000-07:00</published><updated>2008-09-30T00:54:56.936-07:00</updated><title type='text'>Running a subset of shoulda tests from the command line</title><content type='html'>Someone finally revealed a solution for something bothering me for a long time: &lt;a href="http://groups.google.com/group/shoulda/browse_thread/thread/5aef44642bbda277"&gt;how to run a subset of shoulda tests&lt;/a&gt;. This should help a lot for those really ugly bugs where my last resort is to look at the logs and see exactly what's going on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5611656633903981530-3947626736312896594?l=beginrescue.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://beginrescue.blogspot.com/feeds/3947626736312896594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5611656633903981530&amp;postID=3947626736312896594' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/3947626736312896594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/3947626736312896594'/><link rel='alternate' type='text/html' href='http://beginrescue.blogspot.com/2008/09/running-subset-of-shoulda-tests-from.html' title='Running a subset of shoulda tests from the command line'/><author><name>pete higgins</name><uri>http://www.blogger.com/profile/06164347683461976036</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5611656633903981530.post-6929936563092955604</id><published>2008-08-01T15:20:00.000-07:00</published><updated>2008-08-01T15:28:42.660-07:00</updated><title type='text'>Apparently code order matters in Ruby</title><content type='html'>I was recently working on some code that had a structure like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;module OuterModule&lt;br /&gt;  class MyObject&lt;br /&gt;    include InnerModule&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  module InnerModule&lt;br /&gt;    def hello&lt;br /&gt;      "hello"&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;include OuterModule&lt;br /&gt;&lt;br /&gt;m = MyObject.new&lt;br /&gt;&lt;br /&gt;puts m.hello&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When I ran it, I would get this unfortunate output:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;test_ruby_class_heirarchy.rb:3: uninitialized constant OuterModule::MyObject::InnerModule (NameError)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I'm too embarrased to list all the &lt;a href="http://en.wikipedia.org/wiki/Voodoo_programming"&gt;voodoo&lt;/a&gt; I tried to get this to work, but simply putting the definition of MyObject below that of InnerModule did the trick:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;module OuterModule&lt;br /&gt;  module InnerModule&lt;br /&gt;    def hello&lt;br /&gt;      "hello"&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  class MyObject&lt;br /&gt;    include InnerModule&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;include OuterModule&lt;br /&gt;&lt;br /&gt;m = MyObject.new&lt;br /&gt;&lt;br /&gt;puts m.hello&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This gives me the expected output:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;hello&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Going into this, I would have never guessed that the order in which I defined things would have this effect.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5611656633903981530-6929936563092955604?l=beginrescue.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://beginrescue.blogspot.com/feeds/6929936563092955604/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5611656633903981530&amp;postID=6929936563092955604' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/6929936563092955604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/6929936563092955604'/><link rel='alternate' type='text/html' href='http://beginrescue.blogspot.com/2008/08/apparently-code-order-matters-in-ruby.html' title='Apparently code order matters in Ruby'/><author><name>pete higgins</name><uri>http://www.blogger.com/profile/06164347683461976036</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5611656633903981530.post-8064831875667223447</id><published>2008-07-11T12:24:00.000-07:00</published><updated>2008-07-11T12:36:36.747-07:00</updated><title type='text'>A stupid reason I like shoulda</title><content type='html'>I've been interested &lt;a href="http://www.thoughtbot.com/projects/shoulda"&gt;shoulda&lt;/a&gt; for a while but hadn't played around with it until today. I really like the idea of seperate contexts and not having to name methods stuff like "test_process_should_create_record_if_one_doesnt_exist". With some playing around though, I found out that shoulda helps me work around &lt;a href="http://www.zenspider.com/pipermail/ruby/2008-June/004145.html"&gt;a bug I found&lt;/a&gt; in flexmock and rails where the teardown method wasn't getting called correctly in my tests.&lt;br /&gt;&lt;br /&gt;As an addendum to that mailing list post, I get this output:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Loaded suite test/unit/test_shoulda_test&lt;br /&gt;Started&lt;br /&gt;inside setup&lt;br /&gt;inside test&lt;br /&gt;inside teardown&lt;br /&gt;.&lt;br /&gt;Finished in 0.069689 seconds.&lt;br /&gt;&lt;br /&gt;1 tests, 1 assertions, 0 failures, 0 errors&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;... when I run this code:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require File.join( File.dirname(__FILE__), '..', 'test_helper' )&lt;br /&gt;require 'test/unit'&lt;br /&gt;require 'flexmock/test_unit'&lt;br /&gt;&lt;br /&gt;class TestTest &lt; Test::Unit::TestCase&lt;br /&gt;  context "This test" do&lt;br /&gt;    setup do&lt;br /&gt;      $stderr.puts "inside setup"&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    teardown do&lt;br /&gt;      $stderr.puts "inside teardown"&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    should "pass" do&lt;br /&gt;      $stderr.puts "inside test"&lt;br /&gt;      assert true&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Thanks shoulda!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5611656633903981530-8064831875667223447?l=beginrescue.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://beginrescue.blogspot.com/feeds/8064831875667223447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5611656633903981530&amp;postID=8064831875667223447' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/8064831875667223447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/8064831875667223447'/><link rel='alternate' type='text/html' href='http://beginrescue.blogspot.com/2008/07/stupid-reason-i-like-shoulda.html' title='A stupid reason I like shoulda'/><author><name>pete higgins</name><uri>http://www.blogger.com/profile/06164347683461976036</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5611656633903981530.post-7083298248499934185</id><published>2008-07-09T15:08:00.000-07:00</published><updated>2008-07-09T15:13:55.806-07:00</updated><title type='text'>Testing Tidbts #1: Be explicit</title><content type='html'>I was recently refactoring some tests (you do refactor your tests, right? hmm, sounds like an idea for another post..) and I came across something like this, trying to test whether a time field on a rails model was updated correctly:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;assert_in_delta mq.ended_at,&lt;br /&gt;                Time.now,&lt;br /&gt;                1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;What's that 1 for at the end? What's the third parameter for assert_in_delta, anyways?&lt;br /&gt;&lt;br /&gt;If I had been more explicit, that might be a little more apparent:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;assert_in_delta mq.ended_at,&lt;br /&gt;                Time.now,&lt;br /&gt;                1.second&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It's a small change, and totally uneccessary in real, working code, but I feel like it improves the readability a great deal.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5611656633903981530-7083298248499934185?l=beginrescue.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://beginrescue.blogspot.com/feeds/7083298248499934185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5611656633903981530&amp;postID=7083298248499934185' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/7083298248499934185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/7083298248499934185'/><link rel='alternate' type='text/html' href='http://beginrescue.blogspot.com/2008/07/testing-tidbts-1-be-explicit.html' title='Testing Tidbts #1: Be explicit'/><author><name>pete higgins</name><uri>http://www.blogger.com/profile/06164347683461976036</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5611656633903981530.post-6707508004222305179</id><published>2008-07-07T14:47:00.000-07:00</published><updated>2008-07-07T14:49:09.873-07:00</updated><title type='text'>Awesome: Easy Join Table Conditions</title><content type='html'>Most of the new-in-edge-rails features elicit a yawn from me (at best), but &lt;a href="http://ryandaigle.com/articles/2008/7/7/what-s-new-in-edge-rails-easy-join-table-conditions"&gt;this one&lt;/a&gt; caught my eye. Some of the projects at work that I assist on could be cleaned up a great deal with this functionality.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5611656633903981530-6707508004222305179?l=beginrescue.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://beginrescue.blogspot.com/feeds/6707508004222305179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5611656633903981530&amp;postID=6707508004222305179' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/6707508004222305179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/6707508004222305179'/><link rel='alternate' type='text/html' href='http://beginrescue.blogspot.com/2008/07/awesome-easy-join-table-conditions.html' title='Awesome: Easy Join Table Conditions'/><author><name>pete higgins</name><uri>http://www.blogger.com/profile/06164347683461976036</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5611656633903981530.post-4724396286427784787</id><published>2008-05-27T14:43:00.000-07:00</published><updated>2009-03-27T15:36:59.724-07:00</updated><title type='text'>sphinx charset_table with unicode character folding</title><content type='html'>In a project at work I needed to have sphinx treat accented characters and their unaccented versions the same, eg: é&lt;accented e=""&gt; is equivalent to e, etc. I took &lt;a href="http://speeple.com/unicode-maps.txt"&gt;this list&lt;/a&gt; I found on the &lt;a href="http://sphinxsearch.com/wiki/doku.php?id=charset_tables"&gt;sphinx wiki&lt;/a&gt; and transformed it into a &lt;a href="http://pastie.caboo.se/204316"&gt;sphinx friendly charset_table&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Now when I do a search for the string "Héctor Lavoe" it matches the string "Hector Lavoe". Awesome!&lt;br /&gt;&lt;br /&gt;Edit: fixed missing "&lt;/accented&gt;é" in first sentence.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5611656633903981530-4724396286427784787?l=beginrescue.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://beginrescue.blogspot.com/feeds/4724396286427784787/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5611656633903981530&amp;postID=4724396286427784787' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/4724396286427784787'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/4724396286427784787'/><link rel='alternate' type='text/html' href='http://beginrescue.blogspot.com/2008/05/sphinx-charsettable-with-unicode.html' title='sphinx charset_table with unicode character folding'/><author><name>pete higgins</name><uri>http://www.blogger.com/profile/06164347683461976036</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5611656633903981530.post-7907199084197203156</id><published>2008-05-27T14:13:00.001-07:00</published><updated>2008-05-27T14:22:53.513-07:00</updated><title type='text'>Splitting long lines in text files with vim</title><content type='html'>Recently I needed to split long lines in a text file, and it took me a few minutes to figure out how to do this neatly in vim. In case I need it again, here's the regexp I used:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;%s/\(.\{250\}[^ ]* \)/\1 \\^M/gc&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;250 is an arbitrary number I picked, and the "^M" part is a newline entered in vim by pressing ctrl-v, ctrl-m. Also, I split the line where there was a space, because I knew the data had frequent spaces and I didn't want to split a word.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5611656633903981530-7907199084197203156?l=beginrescue.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://beginrescue.blogspot.com/feeds/7907199084197203156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5611656633903981530&amp;postID=7907199084197203156' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/7907199084197203156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/7907199084197203156'/><link rel='alternate' type='text/html' href='http://beginrescue.blogspot.com/2008/05/recently-i-needed-to-split-long-lines.html' title='Splitting long lines in text files with vim'/><author><name>pete higgins</name><uri>http://www.blogger.com/profile/06164347683461976036</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5611656633903981530.post-1783065325424485912</id><published>2008-03-25T11:04:00.000-07:00</published><updated>2008-03-25T13:54:56.553-07:00</updated><title type='text'>ActiveRecord #find syntax and you</title><content type='html'>I've recently been adding eager-loading of ActiveRecord associations into a project at work, and I've run into a few problems because of how the original #find queries were wrtten. I did a little research, and found out how you can help out AR a bit and save yourself (and me) some hassle.&lt;br /&gt;&lt;br /&gt;The easiest way to query AR is to simply use an id, like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;User.find(10)&lt;/pre&gt;&lt;br /&gt;This uses this sql, nicely referenced by the table name:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;SELECT * FROM users WHERE (users.`id` = 10)&lt;/pre&gt;&lt;br /&gt;The downside to this is that a plain #find call will throw an exception if no record exists, and that’s not good (unless caught, the client will see a 500 at that point).&lt;br /&gt;&lt;br /&gt;We’ve been getting around this by using find calls like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;User.find( :all, :conditions =&gt; ['id = ?', 10] )&lt;/pre&gt;&lt;br /&gt;Which generates this sql:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;SELECT * FROM users WHERE (id = 10)&lt;/pre&gt;&lt;br /&gt;This way is good because it will return nil if no record is found, instead of throwing an exception. The subtle downside is that the string in the conditions parameter is copied directly into the sql string, because AR doesn’t know how to do anything with it.&lt;br /&gt;&lt;br /&gt;If instead you use a hash for the conditions parameter, like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;User.find( :all, :conditions =&gt; { :id =&gt; 10 } )&lt;/pre&gt;&lt;br /&gt;AR knows that you’re referencing a column from that model’s table, and gives you the safe sql with no bad exception aftertaste:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;SELECT * FROM users WHERE (users.`id` = 10)&lt;/pre&gt;&lt;br /&gt;As an added bonus, because AR is allowed to do it’s magic, if you decide to pass it an array instead of a single integer, it can do the right thing without you having to change your #find code:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;User.find( :all, :conditions =&gt; { :id =&gt; [10,12] } )&lt;/pre&gt;&lt;br /&gt;Which automatically comes out as:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;SELECT * FROM users WHERE (users.`id` IN (10,12))&lt;/pre&gt;&lt;br /&gt;Summary:&lt;br /&gt;&lt;br /&gt;Don’t do this: &lt;pre&gt;User.find(10)&lt;/pre&gt; or this: User.find( :all, :conditions =&gt; ['id = ?', 10] ).&lt;br /&gt;&lt;br /&gt;Do this: &lt;pre&gt;User.find( :all, :conditions =&gt; { :id =&gt; 10 } )&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5611656633903981530-1783065325424485912?l=beginrescue.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://beginrescue.blogspot.com/feeds/1783065325424485912/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5611656633903981530&amp;postID=1783065325424485912' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/1783065325424485912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/1783065325424485912'/><link rel='alternate' type='text/html' href='http://beginrescue.blogspot.com/2008/03/activerecord-find-syntax-and-you.html' title='ActiveRecord #find syntax and you'/><author><name>pete higgins</name><uri>http://www.blogger.com/profile/06164347683461976036</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5611656633903981530.post-8167454031713378301</id><published>2008-03-17T15:09:00.000-07:00</published><updated>2008-05-27T14:53:24.601-07:00</updated><title type='text'>Rescue Me!</title><content type='html'>With all the talk recently about elegant nil handling in Ruby (like &lt;a href="http://weblog.raganwald.com/2008/01/objectandand-objectme-in-ruby.html"&gt;andand&lt;/a&gt; and &lt;a href="http://recursive.ca/hutch/2007/11/22/a-little-unnecessary-smalltalk-envy/"&gt;if_not_nil&lt;/a&gt; and &lt;a href="http://ruby.tie-rack.org/53/a-better-try-chaining-methods-and-nil/"&gt;#try&lt;/a&gt;), I was surprised that no one mentioned using rescue.&lt;br /&gt;&lt;br /&gt;Surely every ruby programmer knows rescue when used with its friend begin, but did you know rescue has a &lt;a href="http://www.ruby-doc.org/docs/ProgrammingRuby/html/intro.html#S4"&gt;statement modifier&lt;/a&gt; form?&lt;br /&gt;&lt;br /&gt;For example, the following throws an exception:&lt;br /&gt;&lt;code&gt;&gt;&gt; [ "Bacon Lettuce Tomato", nil ].collect {|s| s.upcase.reverse[0,6].reverse }&lt;br /&gt;NoMethodError: You have a nil object when you didn't expect it!&lt;br /&gt;The error occurred while evaluating nil.upcase&lt;br /&gt;       from (irb):15&lt;br /&gt;       from (irb):15:in `collect'&lt;br /&gt;       from (irb):15&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Adding rescue nil after that ugly bit of method chaining gets me this:&lt;br /&gt;&lt;code&gt;&gt;&gt; [ "Bacon Lettuce Tomato", nil ].collect {|s| s.upcase.reverse[0,6].reverse rescue nil }&lt;br /&gt;=&gt; ["TOMATO", nil]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;... and rescue "" gets me this, useful if I want to return all the same types:&lt;br /&gt;&lt;code&gt;&gt;&gt; [ "Bacon Lettuce Tomato", nil ].collect {|s| s.upcase.reverse[0,6].reverse rescue "" }&lt;br /&gt;=&gt; ["TOMATO", ""]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;I haven't used this other than playing around in a console, so I don't really know if this has nasty side effects or not. Maybe there's a reason all these Ruby gurus haven't mentioned it...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5611656633903981530-8167454031713378301?l=beginrescue.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://beginrescue.blogspot.com/feeds/8167454031713378301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5611656633903981530&amp;postID=8167454031713378301' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/8167454031713378301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5611656633903981530/posts/default/8167454031713378301'/><link rel='alternate' type='text/html' href='http://beginrescue.blogspot.com/2008/03/rescue-me.html' title='Rescue Me!'/><author><name>pete higgins</name><uri>http://www.blogger.com/profile/06164347683461976036</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
