– we create awesome web applications

I was frustrated by ⌘Q and ⌘W proximity for a long time. Long, long time. Seriously, long time.

It hits me the most with browsers since I usually open and close quite a lot of tabs during the day. And I tend to do it from keyboard, so sometimes I just hit ⌘Q when I only intended ⌘W.

It just happened again.

But this time I suddenly realized that I can easily remap it. I was using this OSX feature for other things, like remapping useless since the typewriter days Caps Lock key, but somehow missed that I can fix this annoying problem too.

If not universally then at least in Chrome (or any other application if needed).

This is really easy:

  1. go to System PreferencesKeyboardKeyboard Shortcuts and choose Application Shortcuts in the left panel.

    Keyboard Shortcuts

  2. click on the + icon to add another shortcut.

  3. Choose Google Chrome as the application and type in exactly, including case Quit Google Chrome as Menu Title. Generally, it should be the exact menu command name in the application that you want to map.

  4. Now, click inside the Keyboard Shortcut field and then press on you keyboard whatever the new shortcut you want. I chose ⌥⇧Q so that it will stay at the same place but wont be as accidentally press-able.

Quit Google Chrome shortcut

⌘Q will not longer work, and the new shortcut will be correctly displayed in the Chrome’s menu:

Chrome Menu

Yeah, I know, MVC is the “Only True Way™”. But sometimes, just sometimes, you need your link_to or html helpers working in the model.

For example, sometimes the cleanest way to implement something is to have to_html in the model (widgets anyone?).

Doing this will most probably require generating some urls, and you need a controller for that. Usually I solved this by passing controller to the to_html function, but it always felt wrong.

Another example is when you are working on an API. You somtimes would like to have an option to add actual URIs of related services inside an xml.

Like in

<articles>
    <article>
        <title>Let my controller go</title>
        <href>http://example.com/articles/123</href>
        <created>2009-05-24T19:09:06Z</created>
    </article>
</articles>

Now how will you implement that? It would be nice if @articles.to_xml just worked, but then how will you generate the href url? url_for is not available in models.

Solution? just make it global and let the purists tear their hairs out! :)

This plugin solves the issues above by making the current controller available from a global function current_controller. (actually it uses Thread local storage, so it will work even in multithreaded Rails environment)

The installation is simple

script/plugin install git://github.com/astrails/let_my_controller_go.git

Or

braid -p git://github.com/astrails/let_my_controller_go.git

Then you can implement the above as

class Article < ActiveRecord::Base
  def href
    current_controller.url_for(self)
  end

  def to_xml(opts = {})
     super opts.merge(:methods => :href, :only => [:title, :created_at])
  end
end

Then Articles.all.to_xml will produce what you need (when running in a context of a web request, i.e. it won’t work from the console).

So, while it might not pass strict software design review, but it is useful. And as with any tool, it’s up to you to use it appropriatly.

Sources are at GitHub.

OK, flame away! /ducks and hides under the desk/

Wouldn’t it be cool if you could just require “http://my-host/my-lib.rb” in ruby?

Now You Can! Using our “http_require” gem! :-)

test.rb:

require "http_require"
# this will download bar.rb and eval it
require "http://example.com/foo/bar.rb"

If a remote file (or one of its local dependencies) requires something that can’t be found locally, it will try to find it remotely from the same location as the parent.

Example

http://example.com/test/foo.rb:

# this will load "http://example.com/test/foo/bar.rb"
# if "foo/bar" is not available locally
require "foo/bar"

Stacktrace

http_require properly sets filename on eval so that the file’s URI appears in the stacktrace:

http://example.com/foo/foo.rb:

puts :foo
require 'bar'
def foo
  bar
end

http://example.com/foo/bar.rb

puts :bar
def bar
  raise
end
$ irb
>> require 'http_require'
=> true
>> require 'http://example.com/foo/bar.rb'
foo
bar
=> nil
>> foo
RuntimeError:
    from http://localhost:2000/bar.rb:3:in `bar'
    from http://localhost:2000/foo.rb:5:in `foo'
    from (irb):3
>>

Installation

sudo gem install astrails-http_require --source http://gems.github.com/

Sources

You can find sources on github

UPDATE:

There seems to be lots of similar comments that I’d like to answer here:

  • Q: This is a HUGE security hole
  • A: No it isn’t. running it directly from the web is no less secure then downloading it and then running locally. you can use same security protections, for example SSH tunnel, or SSL like you would for any other kind of ‘code delivery’ e.g. rsync, scp etc. If you control the source and the ‘tunnel’ then this is no less secure, and if you don’t, then no other method is secure unless you start encrypting/signing files.

  • Q: Why on earth would you do something crazy like this?
  • A: It is kind of cool :) Seriously though I do have a real usage in mind for this (more on that later), meanwhile consider rails app templates (rails -m app_template.rb) which do support running templates form the web, and no one seems to be crying out laud about a huge security hole :) Unfortunately though rails templates do not support (not out of the box) breaking down such remote templates into subfiles. you will need to do manual path mangeling (see app_lego for example). I guess http_require can be used to do it cleaner.

On one of our projects we needed to do some caching for an action with an expensive db query. Fragment caching took care of the rendering but we needed a way to skip the db if we have a cache hit. And checking for an existence of the fragment file in the controller just didn’t seem right.

Lazy evaluation to the rescue.

controller

@items = Item.lazy.paginate

view

<% cache ("fragment...") do %>
   <%= render :collection => @items %>
<% end %>

@items is a placeholder for the result of calling paginate which will not be actually executed until @items is used in any way (calling any method on it, like each, or to_s). And if the fragment is cached then @items is not accessed and so no db query is made.

We re-implemented the lazy evaluation recently for our new project with a much cleaner syntax and simpler implementation. We packaged it as lazyeval gem.

Sources can be found at github. The interesting part is in lazyeval.rb which is just 28 lines long. Check it out …

The basic idea is to return a placeholder object that ‘remembers’ what needs to be done once it is used.

2 options:

  1. foo.lazy.bar(params) - this will return a placeholder that will call method bar on the object foo with params once used.
  2. foo.lazy {|o| o.bar } - this will return a placeholder that will call the block passing the object foo as a parameter.