i do work in php as well, grudgingly, and i found myself missing ends_with? today in ruby. seeing this activesupport port for php post makes me miss ruby even more. as most of the commenters point out, it’s lipstick on a pig.
Dynamic Instantiation of Property Accessors 1
Jay Fields describes a scenario for using dynamic method definition instead of method missing. Today i think i found a reason to use both method missing and dynamic method definition, for both speed and safety.
I have an ActiveRecord class that uses a serialized Hash as one of its parameters. There are about a dozen keys in that hash that are most frequently used, however there may be others. I want those most frequently used keys to be exposed as methods on the containing object like this:
class Query < ActiveRecord::Base
DYNAMIC_METHODS = [:my_key1, :my_key2, :my_other_key_exposed_as_method ]
serialize :params
def method_missing(methodname, *args)
if self.class.methods.include?(methodname)
super
elsif DYNAMIC_METHODS.include?(methodname.to_sym)
_build_dynamic_fields
self.send(methodname, *args)
else
super
end
end
# dynamically alias these methods to retrieve their results from the
# params object
def initialize(initparams=nil)
super
end
# called if a caller ever requests one of the dynamic methods above
def _build_dynamic_fields()
DYNAMIC_METHODS.each() do |m|
(class << Query;Query; end).class_eval do
define_method m do |*args|
return nil if params.nil?
self.send(’params’).send(’[]’, m.to_sym) rescue nil
end
end
end
end
Samsung SyncMaster 245BW
Highly recommended monitor - just bought yesterday for $419.00, and the picture quality and ability to run 1920×1200 is just incredible. Also, this post on FutileShop shows how to get it to rotate into portrait orientation.
no mod_ruby is damaging Ruby’s viability 1
Peter Cooper’s post on the lack of a ‘mod_ruby’ is dead on. I am working on a site with millions of hits per month and i couldn’t even begin to credibly suggest that we do any ‘production’ work in ruby.
It is not (just) that Rails isn’t reliable enough. Deployment isn’t brain dead enough. You have to run mongrel, tune the number of instances, then run monit and have it restarting mongrel instances. Then have something or someone watching monit when it fails to restart mongrel every month or so.
Deploying rails requires a significant amount of brainpower from an above average engineer to design the deployment. PHP requires only a rudimentary understanding of FTP.
Math.max or why is there no integer maximum function in ruby
There is no Math.max function. Instead, use an array:
>> [2,3,4].max
=> 4
I would argue there should be, because it is not intuitively obvious that this type of integer comparison would live off of an array. One argument could be that the array approach allows for non-integer types to be compared, and that the increase in flexibility has an increase in obscurity as its side-effect…
>> ["chicken","fox"].max
=> "fox"
parsing excel files in ruby - the parseexcel gem 4
Highly recommended gem does exactly what it says. Here’s the code to turn an entire worksheet from an excel doc into a multi-dimensional array:
wb = Spreadsheet::ParseExcel.parse(filename)
rows = wb.worksheet(worksheet).map() { |r| r }.compact
grid = rows.map() { |r| r.map() { |c| c.to_s('latin1')}.compact rescue nil }
Just ‘gem install parseexcel’ (though i installed from source before i realized it was a pre-packaged gem).
Starting a thread in environment.rb - don’t do it!
I have a project that requires a standalone server for background processing. I could have used backgroundrb but it seems like overkill, and it has this comment on the documentation page, which is a year old, and which tells me the gem is not in active development.
WARNING: start/stop/restart is broken in 0.2.1, please use the server script directly until we have figured out the issue.
So, in development mode, rather than start a standalone server, I put this code in development.rb:
Thread.new do
Server.start()
end
For reasons i’ve yet to determine, because the thread is started in the initialization code, the file include logic doesn’t work properly. Now, this could be a problem with DRb, which is how the server talks with the rest of the app, or it could be a problem with the file include logic in rails. Either way, the first attempt to contact the server works, and on the second attempt to contact the server, we get this error:
A copy of Server has been removed from the module tree but is still active!
For now, I’m just running the server using script/runner in a separate process, and it works fine.
really really long regular expressions - don’t do it!
For one of my projects, we have a list of around 100 domains in a ‘blacklist’. Because of the way the blacklist works, we need to allow non-programmers to enter sites using simple wildcards. Then I convert that into a regular expression:
Regexp.new("^#{regexp.gsub(".","\\.").gsub("*",".*")}$",Regexp::IGNORECASE)
When spidering sites, if a site we find is in this list, we exclude it. I was building a regular expression of all these sites and ‘unioning’ them all together into one mega-regular expression. Then, to see if a domain is on the ‘blacklist’, i just do:
domain =~ my_mega_regex
However, what I found is that a regular expression longer than about 159 separate predicates causes ruby to segfault. This happens on ruby 1.8.4 and 1.8.5. Here’s the simplist code I can repro this with:
r=Regexp.new(/^$/);1.upto(1000) { |i| r= Regexp.union(r,Regexp.new("^#{i}$"));puts i unless "foo" =~ r }
controller variables named @url - don’t do it!
Don’t name your variable @url, then use any of the url helpers such as url_for, link_to_remote, etc. If you do, you’ll get this error:
You have a nil object when you didn't expect it!
The error occurred while evaluating nil.rewrite
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/base.rb:522:in `url_for' /usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_view/helpers/url_helper.rb:27:in `send' /usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_view/helpers/url_helper.rb:27:in `url_for' /usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_view/helpers/prototype_helper.rb:242:in `remote_function' /usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_view/helpers/prototype_helper.rb:133:in `link_to_remote' #{RAILS_ROOT}/app/views/seo/_listtable.rhtml:103:in `_run_rhtml_47app47views47seo47_listtable46rhtml' #{RAILS_ROOT}/app/views/seo/list.rhtml:3:in `_run_rhtml_47app47views47seo47list46rhtml' /usr/bin/rdebug-ide:16:in `load' /usr/bin/rdebug-ide:16 -e:4:in `load' -e:4
RubyRescue Re-launched
I had lunch with a friend today, and he convinced me that i should start blogging again. So, here it is, the re-launch of rubyrescue.com.