me.stub!(:code!)

Feb 26 2010

XRefresh on OSX Snow Leopard (using RVM)

Installing XRefresh (http://xrefresh.binaryage.com/#osx) was not too too straightforward with RVM… here is how I did it.

Before we get started…

  1. You have RVM don’t you? `sudo gem install rvm`
  2. I like to use RVM’s readline and iconv: `rvm install readline; rvm install iconv`
  3. At the time of this writing, rvm seems to set ARCHFLAGS during the readline or iconv install, which seems to mess with the ruby install (the next step). Simple solution though… open a new shell for the rest of the steps. Ignore this… I had this problem only because I had arch_flags=x86_64 in ~/.rvmrc, a relic of my 10.5 system.
  4. Ruby Cocoa needs —enabled-shared, which supposedly slows down Ruby a lot (REE by 20%). Since I primarily use REE+Passenger for my Rails development I just decided to use a different version of Ruby for XRefresh… here we go.
Comments (View)
Nov 19 2009

rvm / ree / nokogiri / gem bundler

(OSX 10.5… rvm installs REE with x86_64 architecture)

Recent steps I took to switch to rvm on my dev machine:

  1. Install rvm (http://rvm.beginrescueend.com/install/).
  2. Set up architecture flags (maybe optional — it seems like it installed x86_64 without this step) (http://rvm.beginrescueend.com/mysql/) (http://sick.snusnu.info/2009/11/04/installing-nokogiri-with-rvm-on-snow-leopard/).
  3. Switch to ree ruby: `rvm ree`.
  4. Install passenger: `gem install passenger` (NO sudo — remember this is rvm) and install the apache module as usual (http://www.modrails.com/install.html)
  5. In order for the mysql gem to install (remember since we’re x86_64), grab the x86_64 version of mysql 5.1 from http://dev.mysql.com/downloads/mysql/5.1.html#macosx-dmg.
  6. REBUILD everything macports for x86_64 :’( — this sucks. Mainly need `sudo port install libxml2 +universal` and `sudo port install libxslt +universal` and `sudo port install libiconv +universal` … that last one required me to uninstall and install a bunch of crap like gettext and readline… uggg…
  7. Set up the build options for nokogiri:
    nokogiri:
      xml2-include: /opt/local/include/libxml2
      xml2-lib: /opt/local/lib
      xslt-dir: /opt/local
      iconv-dir: /opt/local
  8. Finally, run `gem bundle` and watch the magic happen!

It’s late… this might not be too coherent.

Comments (View)
Aug 20 2009

stream itunes => songbird with SSH tunnel

Ok, so this might not work with the latest version of iTunes since we all know how much Apple likes to screw with iTunes… This works for me because I have a ReadyNAS NV+ at home that offers its own iTunes-like DAAP server which is apparently compatible with the Songbird DAAP plugin.

The SSH tunnel:

ssh -p <ssh_gateway_port> -L <some_random_local_port>:<itunes_host_ip>:3689 <username>@<ssh_gateway_ip>

In Songbird, with the DAAP add-on, go to File -> New DAAP Library… and fill in daap://localhost:<some_random_local_port>.

Boom, music streaming…

Comments (View)
Aug 10 2009

rails 2.2.2 => 2.3.3.1: two small discoveries

In my long overdue upgrade from 2.2.2 to 2.3.x I found a couple interesting, yet undocumented/unpublicized tidbits:

  • config.gem ‘BlueCloth’, :lib => ‘bluecloth’ should be config.gem ‘bluecloth’ (since gem install BlueCloth installs the old 1.x version while gem install bluecloth gives us the new and improved 2.x version). I was getting “uninitialized constant ActionView::Helpers::TextHelper::Markdown” when using markdown() in views.
  • I noticed in the changelog that CGI::Session::CookieStore was changed to ActionController::Session::CookieStore. I was curious… what happened to CGI:Session::CookieStore::TamperedWithCookie and the implementation of untamperable cookies? It was extracted in a cool class called ActiveSupport::MessageVerifier (also see ActiveSupport::MessageEncryptor)! For some custom untamperable cookie stuff, I had implemented a module called LevainCookies… but that’s no longer needed! Thanks Rails!
Comments (View)
May 13 2009

Rails HTML list helper

I posted a HTML list view helper here: http://gist.github.com/110754

h4x0r?

This is so I can do:

  
<% ul_nav do |ul| %>
  <%= ul.link_to "hello", '#' %>
  <%= ul.link_to "middle", '#' %>
  <%= ul.link_to "goodbye", '#' %>
<% end %>
 
<ul class="nav">
  <li class="first"><a href="#">hello</a></li>
  <li><a href="#">middle</a></li>
  <li class="last"><a href="#">goodbye</a></li>
</ul>
 
<% ul_nav do |ul| %>
  <% ul.li do %>
    <%= link_to "Hello", '#' %>, my child...
  <% end %>
  <% ul.li do %>
    <% 3.times do %>
      <%= link_to "middle!", '#' %>
    <% end %>
  <% end %>
  <%= ul.link_to "goodbye", '#' %>
<% end %>
 
<ul class="nav">
  <li class="first">
    <a href="#">Hello</a>, my child...
  </li>
  <li>
    <a href="#">middle!</a>
    <a href="#">middle!</a>
    <a href="#">middle!</a>
  </li>
  <li class="last"><a href="#">goodbye</a></li>
</ul>
Comments (View)
May 06 2009

factory_girl callbacks

Eh, I don’t know if this is necessary, but I added callbacks to factory girl (http://github.com/agibralter/factory_girl/tree/master).

Factory.define :user_with_verified_email do |f|
  f.email                   { Factory.next(:email) }
  f.login                   { Factory.next(:name) }
  f.terms_and_conditions    1
  f.password                'password'
  
  f.add_callback(:after_save) do |user|
    user.verify_email!
  end
  f.add_callback(:before_save) do |user|
    # I don't really know what you would want to do here...
    # The dynamic attributes seem to handle most cases for
    # a before_save callback
  end
end

The callbacks only get called during Factory.create, not build, etc.

Comments (View)
Apr 26 2009

cucumber negative expectations

*update* I forgot to include matcher block arguments… code is fixed below

A ton of my Then step definitions have this pattern:

Then %r{should( not)? be happy$} do |should_not|
  # ...
end

Dealing with the conditional should or should not got annoying, and I thought about some hardcore solutions (seen in this LH ticket)… but I ended up with a simpler solution with Andrew Vit’s help:

require 'singleton'

module NegativeExpectationsHelper
  
  class State
    
    include Singleton
    
    def is_negative?
      @negative === true
    end
    
    def is_negative!
      @negative = true
    end
    
    def restore!
      @negative = false
    end
  end
  
  module ObjectExpectations
    
    def self.included(base)
      base.class_eval do
        alias_method :original_should, :should
        alias_method :original_should_not, :should_not
        
        def should(*args, &block)
          should_if_true(!State.instance.is_negative?, *args, &block)
        end

        def should_not(*args, &block)
          should_if_true(State.instance.is_negative?, *args, &block)
        end
      end
    end
    
    private
    
    def should_if_true(cond, *args, &block)
      cond ? self.send(:original_should, *args, &block) : self.send(:original_should_not, *args, &block)
    end
  end
  
  def negative_expectations_if(cond)
    raise "expected block" unless block_given?
    State.instance.is_negative! if cond
    yield
    State.instance.restore! if cond
  end
end

class Object
  include NegativeExpectationsHelper::ObjectExpectations
end

World(NegativeExpectationsHelper)

That’s probably cumbersome (whoa, I just made a typo, “cucumbersome” and thought it would make for a nice cucumber inside joke) since I’m a little bit of a ruby meta-programming n00b. But anyway, now I can do: 

Then %r{should( not)? be happy$} do |should_not|
  negative_expectations_if(should_not) do
    should be_happy
  end
end
Comments (View)
Apr 13 2009

rspec example organization

If I find myself writing it blocks that contain the word “if” I like to refactor into sub-describe blocks:

describe User do

  it "should be cool if wearing pants" do
    # ...
  end
end

# VS...

describe User do
  
  describe "wearing pants" do
    
    before(:each) do
      # wearing pants setup
    end
    
    it "should be cool" do
      # ...
    end
  end

  describe "not wearing pants" do
    
    before(:each) do
      # not wearing pants setup
    end

    it "should not be cool" do
      # ...
    end
  end
end

Yes… the second way is more verbose, but in the long run it will help organize your specs specifically and your thoughts in general.

Comments (View)
+

rails cookie session store

At first, I really loved the rails CookieStore for sessions… it seemed so elegant and carefree to let the client take care of its own data. Actually, I still like the idea a lot and it works well in most cases.

One problem: if you want to iframe/widgetize your site on another, you’ll have trouble. The security “features” of many browsers (such as Safari) will ignore Set-Cookie headers from domains other than the site you navigate to. The cookies in the CookieStore sessions are constantly changing on the server side, but will never get set on the client… as a result, the user state breaks.

So… memcached (or any server-side session store) to the rescue. Set the session “key” once on the client (I think browsers will honor the Set-Cookie header for a <script src=”…”/> request) and go from there!

Comments (View)
Page 1 of 1