Using define_method to overwrite a class' initialize as an example of overwriting a method from your mock, version 2 1

Posted by Tim Connor Fri, 30 Nov 2007 22:40:00 GMT

Last year, I wrote an article about redefining an instance method from a module via alias_method. I understand better how extend/include work together now (and the ClassMethods include patterns and whatnot) so I am little embarrassed at my earlier confusion, but there is one concrete thing I wanted to add/simplify.

If you are mocking and don’t need to keep a reference to the old method, using define_method might be marginally cleaner.


def self.included(associator_class) 
  associator_class.send(:define_method, :initialize, instance_method(:initialize))
end
This is handier because you can skip the method definition/reference logic and just do it in situ, for instant-stubification

ClassToBeIntercepted.send :define_method, :method_to_be_nuked, proc {return 'nuked'}

Leopard quicklook from the commandline 2

Posted by Tim Connor Thu, 29 Nov 2007 00:58:00 GMT

I’ve come across a number of these, but here is my favorite (put this in your .profile):

function ql()
{
qlmanage -p "$@" >& /dev/null
}
I don’t like how people are backgrounding it or trying to get fancy, primarily, because any of the scripts claiming to make the spacebar-kills-QL functionality work, didn’t. This way CTRL-C does what it should, instead. It also maintains the qlmanage functionality of slideshowing multiple params.

Be careful when you paste it to convert curly quotes back to straight quotes. >:|

Validating that at least one attribute in a list is present: validates_presence_of_any

Posted by Tim Connor Tue, 20 Nov 2007 05:10:00 GMT

Make a lib/custom_validations.rb file, with these contents

module CustomValidations
  def validates_presence_of_any(*attrs)
    options = attrs.last.is_a?(Hash) ? attrs.pop.symbolize_keys : {}
    attrs   = attrs.flatten
    send(validation_method(options[:on] || :save)) do |record|
      return if options[:if] && !evaluate_condition(options[:if], record)
      attr_list = attrs.map{|a| a.to_s.humanize}.to_sentence(:connector => "or", :skip_last_comma => true)
      record.errors.add :base, "Either #{attr_list} needed." if attrs.all?{ |attr| record.send(attr).blank?}
    end
  end
end
and then “extend CustomValidation” in your model. Then you can

 validates_presence_of_any :first_attr, :second_attr, :third_attr

Thanks to bitsweat on #caboose for help with a succinct name that follows the convention.

Doing a rails custom validator with-out using validates_each

Posted by Tim Connor Tue, 20 Nov 2007 03:01:00 GMT

I wanted to do a custom validator (forthcoming post) that validates that at least one out of a list of attributes is present (validates_presence_of_any). Unfortunately, all the examples I could find use validates_each (see here for a decent example on the topic in general), and since mine depends on the list as a whole, that doesn’t quite fit. So I just stole some of the guts of validates each, to get the magic reference to the record object. As a bonus, then my validation conforms to other validation conventions, like accepting :if => in an options hash.
  def self.validates_your_funky_non_validates_each_using_way(*attrs)
    options = attrs.last.is_a?(Hash) ? attrs.pop.symbolize_keys : {}
    attrs   = attrs.flatten
    # Declare the validation.
    send(validation_method(options[:on] || :save)) do |record|
      return if options[:if] && !evaluate_condition(options[:if], record)
       #put real code using attrs and record here
      record.errors.add :base, "monkey", if record.primate?
    end
  end

A graphical IE installer for OS X 2

Posted by Tim Connor Mon, 19 Nov 2007 17:57:00 GMT

Finally. I had been installing wine using MacPorts, just so I could run the ies4linux script. I ran into some problems with that on Leopard, namely that the wine port was broken for Leopard. But now Mike Kronenberg is maintaining current Darwine builds, and has made a graphical installer for ies4linux, on OS X. From the bottom of my heart, thank you Mike.

Wine on Leopard OS X 10.5 via MacPorts is broken 3

Posted by Tim Connor Fri, 16 Nov 2007 03:55:00 GMT

The wine port (MacPorts) for version 0.9.49 for Leopard is broken and fails with a

./crtdll.spec:44: external symbol 'CRTDLL__basemajor_dll' is not a function
There is a bug in their Trac about it, if you have an account.

rails javascript helper - capturing an additional level of block nesting within a content_for

Posted by Tim Connor Thu, 08 Nov 2007 23:19:00 GMT

When making a helper that takes a block, the yield causes it to output at the point of being called in the template. If the reason for the helper is to populate a content_for/yield variable, such as to put javascript in the head tag, you get duplicate output: once where it belongs when the content_for is yielded, and once where you call your helper. Instead, make use of capture(&block).

This helper
  
def javascript(&block)
  content_for(:header) do
    "<script type=\"text/javascript\">//<![CDATA[#{capture(&block)}//]]></script>" 
  end
end
when called like this
 
<%javascript do%>
    alert('hi')
<%end%>
results inthis
<html>
<head>
<script type=\"text/javascript\">//<![CDATA[
alert('hi')
//]]></script>
if you have a yield :header in your head tag.