Monday, July 26, 2010
Writing methods which write methods
http://www.raulparolari.com/Ruby2/define_method - Here is a nice writeup showing how to use Ruby's define_method feature.
Labels:
metaprograming,
ruby
Sunday, July 25, 2010
Suggestion for Community Service Hours - Curating a Community Calendar
http://elmcity.cloudapp.net/ - This is an interesting website which allows you to provide calendar events in several different formats. A great community project would be to aggregate school events in a locality.
Sunday, July 11, 2010
Using ImageMagick To Create Horizontally Repeating Background Image
- Find an image that you want to slice vertically, which I'll refer to as the base image. This slice is what will be repeated across the background of the web page.
- Use the
identify home_page.jpgcommand to find out some details about the base image. The result of this command looks like this:home_page.jpg JPEG 1300x1380 1300x1380+0+0 8-bit DirectClass 736KiB 0.240u 0:00.240 - For our purposes, the first set of numbers is sufficient. They hold the width and height.
- The next step involves extracting a vertical slice (top to bottom) from the base image. Use this command:
convert -extract 10x1380+0+0 home_page.jpg body_background.png. Notice that you can vary the width of the slice using the first number. In this case, I use 10 but some other number is probably more appropriate for you. - If you want to test various widths, you can 'tail' the background image using
display -update 1 body_background.pngwhich redisplays the image every second. - Once you've got the vertical slice, you need to integrate it with your web page.
- Use CSS similar to this:
body { background-image: url('body_background.png'); background-repeat: repeat-x; }
Thursday, July 01, 2010
Using module_eval to Define Instance Methods in a Ruby Gem to Enable Per-Model Configuration
In the last post, I mentioned that I wrote a small gem to post changes to ActiveRecord models to Twitter. In that version, the configuration was handled by a YAML file. I wanted to evolve the gem so that developers could switch Twitter accounts for each model.
Basically, I wanted to able to the use the following:
class Place < ActiveRecord::Base
alastrina :twitter => { :username => 'alastrina_gem', :password => 'QQQQQQ' }
end
After a bit of tinkering and searching, I decided to use the following code in my gem.
ALASTRINA_CONFIGURATION_FILE = 'config/alastrina.yml'
module Alastrina
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def alastrina hash
module_eval do
def configuration
throw "Missing #{ALASTRINA_CONFIGURATION_FILE}" unless File.exists? ALASTRINA_CONFIGURATION_FILE
@config ||= YAML::load(File.read(ALASTRINA_CONFIGURATION_FILE))
end
if hash[:twitter]
def send_to_twitter?
true
end
eval"def twitter_username\n\"#{hash[:twitter][:username]}\"\nend\n"
eval "def twitter_password\n\"#{hash[:twitter][:password]}\"\nend\n"
else
def send_to_twitter?
@twitter_flag ||= !configuration['twitter'].blank?
end
def twitter_username
@twitter_username ||= configuration['twitter']['username'] if send_to_twitter?
end
def twitter_password
@twitter_password ||= configuration['twitter']['password'] if send_to_twitter?
end
end
end
end
end
def after_save
if send_to_twitter?
require 'twitter'
throw "Missing Twitter userid" if twitter_username.blank?
throw "Missing Twitter password" if twitter_password.blank?
send_via_twitter
end
end
private
def send_via_twitter
if changes.size > 0
httpauth = Twitter::HTTPAuth.new(twitter_username, twitter_password)
client = Twitter::Base.new(httpauth)
begin
client.update(changes.to_yaml)
rescue
RAILS_DEFAULT_LOGGER.error "alastrina.send_via_twitter; Unable to send change. Message[#{$!}] Change[#{changes.to_yaml}]"
end
end
end
end
ActiveRecord::Base.class_eval { include Alastrina }
The key insight to this code is how the hash passed on the alastrina of the Model is passed down into the instance. The code is fairly straightforward once you see what the eval is doing.
Labels:
ActiveRecord,
gem,
module_eval,
ruby,
twitter
Subscribe to:
Posts (Atom)

