% ruby -v -ryaml -e 'y({:a => 2})'
ruby 1.8.4 (2005-12-22) [powerpc-darwin8.3.0]
---
:a: 2
Confirmed kill!
This should fix all 1.8-related rubygem compatibility issues that occurred in 1.8.3.
% ruby -v -ryaml -e 'y({:a => 2})'
ruby 1.8.4 (2005-12-22) [powerpc-darwin8.3.0]
---
:a: 2
Confirmed kill!
This should fix all 1.8-related rubygem compatibility issues that occurred in 1.8.3.
The HTTP specification allows browsers to perform conditional requests avoiding use of extra bandwidth if the page was not modified. In 43 Things I added support for conditional HTTP requests to some of our RSS feeds to save bandwidth.
As an alternative you can use the built-in page caching which uses the web server to automatically handle conditional requests, but this is not always appropriate. If you have content that is customized for a user, like home page links for logged-in users, the page cache won't work because different users will have different home page links. In our case it was simpler to add a few lines to our code than to set up a shared space to use as a page cache.
The solution I chose can be applied to any page you can determine a last modified time for.
require 'inline'
class Inline::ObjC < Inline::C
def initialize(mod)
super(mod)
end
def import(header)
@src << "#import #{header}"
end
end
class MyClass
inline(:ObjC) do |builder|
builder.import "<Foundation/NSString.h>"
builder.add_compile_flags '-x objective-c', '-framework Foundation'
builder.c %q{
void test() {
printf("%s\n", [@"Hello World!" cString]);
}
}
end
end
MyClass.new.test
I love it... OSX hackers, have at it...
def foo(*args)
[args].flatten.map do |arg|
# ...
end
end
def foo(*args)
Array(args).map do |arg|
# ...
end
end
and argues their (ugly) necessity. I think both examples fail to hit the mark (or there is a typo?) as they've ensured the initial codition simply by using *args. Allowing them to state the problem in a straightforward fashion:
def foo(*args)
args.flatten.map do |arg| # if you are trying to combine a bunch of arrays
# ...
end
end
def foo(*args)
args.map do |arg|
# ...
end
end
which, is much more natural. If I had to guess, I'd say they meant to not put the splat in front of args. I find using splat to be a better fit.
A while back I was thinking about MVC and how URLs are built and came to the conclusion that every model should know what its URL is. I don't think it is the responsibility of the Controller to know this, and certainly not the view.
Since Rails uses a Hash to represent a URL, I thought it would be easy to just add a method to every Model that would return a Hash representation of the URL and override url_for to perform the expansion from a model into its URL Hash.
It turns out that it was easy. After some enhancements by Ryan that adds defaults we came up with the following:
class ApplicationController < ActionController::Base
def url_for(options = {}, *params)
if options.include? :model then
model = options.delete(:model)
defaults = {
:action => 'show',
:id => model.id,
:controller => model.class.name.downcase,
}
defaults = defaults.merge model.url_params if model.respond_to? :url_params
options.delete :only_path if defaults.include? :only_path
options = defaults.merge options
end
return super(options, *params)
end
end
You can use the modified url_for like this:
@model = Model.find some_id url_for :model => @model url_for :model => @model, :action => 'edit' redirect_to :model => @model link_to @model.name, :model => @model
Sometimes the defaults aren't good enough though. To override them you add a url_params method to your model. In Trackmap I store enough information about a flickr photo to generate its flickr URL in the database and my url_for modification (with a bit of cheating) makes this very clean:
class Photo < ActiveRecord::Base
#...
def url_params
return { :host => 'flickr.com', :controller => 'photos',
:action => flickr_nsid, :id => flickr_photo_id,
:only_path => false }
end
end