Cory O'Daniel – These are just words Software development, thoughts, and randomness

2Nov/100

methods_like helper for finding ruby methods

Here is a little gem I have in my ~/.irbrc I use it a lot when debugging code. I tend to use call #methods a lot on objects to figure out how they quack.

Sometimes I can remember kinda what a method's name is I want to use, but doing something like the following can generate a huge amount of output especially when working with ActiveRecord

1
my_object.methods.sort

So I threw together this little method that adds to ruby's base Object class

1
2
3
4
5
6
7
8
class Object
  def methods_like(pat)
    pattern =  pat.is_a?(String) ? /#{pat}/ : pat
    self.methods.sort.select{|m|
      m =~ pattern
    }
  end
end

Now from IRB, Rails console, or Padrino console you can do things like:

my_collection.methods_like(/^update/) #=> [ array of method names that start with update ]
user.methods_like("name") #=> [ :first_name, :last_name, :etc ]
Array.new.methods_like "sort" #=> ["sort", "sort!", "sort_by"]

Its a handy little snippet when you can't remember an exact method name, and generally for me works faster than googling for it. Toss it in your ~/.irbrc and tell me what you think.

UPDATE
I added some more functionality for getting additional methods (private, protected, singleton):

class Object
  # pattern - string or pattern to match
  # access  - :public, :private, :protected, :singleton, :all
  def methods_like(pattern, access = :public, details = false)    
    master_method_list = case access
    when :public then self.methods
    when :private then self.private_methods
    when :protected then self.protected_methods 
    when :singleton then self.singleton_methods
    when :all
      (
        self.methods            +
        self.private_methods    +
        self.protected_methods  +
        self.singleton_methods
      ).uniq
    end
 
    matched_method_list = master_method_list.sort.select{ |m| m =~ ( pattern.is_a?(String) ? /#{pattern}/ : pattern ) }
 
    if !details
      matched_method_list
    else
      details_list = {}
 
      matched_method_list.each do |current_method|
        details_list[current_method] = method_details(current_method)
      end
 
      details_list
    end
  end
 
  # Returns details about method
  def method_details(current_method)
    current_method = current_method.to_s
    access_level = if self.methods.include?(current_method)
      :public
    elsif self.private_methods.include?(current_method)
      :private
    elsif self.protected_methods.include?(current_method)
      :protected
    elsif self.singleton_methods.include?(current_method)
      :singleton
    end
 
    {
      :owner    => self.method(current_method).owner,
      :arity    => self.method(current_method).arity,
      :receiver => self.method(current_method).receiver,
      :access   => access_level
    }
  end
end

Now you can do:

variable.methods_like pattern, :private #=> Array of private methods with pattern
variable.methods_like pattern, :all, true #=> Hash of methods with additional details

If you pass 'true' for details you will get a hash that looks like:

Array.new.methods_like "sort", :all, true #=>
{
  "sort_by"=>{:owner=>Enumerable, :access=>:public, :receiver=>[], :arity=>0}, 
  "sort!"    =>{:owner=>Array, :access=>:public, :receiver=>[], :arity=>0}, 
  "sort"     =>{:owner=>Array, :access=>:public, :receiver=>[], :arity=>0}
}

Access options available are :public, :private, :singleton, :protected, :all

Post to Twitter Post to Digg Post to Facebook Post to Reddit Post to StumbleUpon

17Apr/100

Padrino, Compass, and Sass – Working happily via Ian Serlin

My cohort, Ian Serlin, discovered this. In a project we are working on we could get Compass to play well with PadrinoRb. It seems like the #sass method doesn't care about the options being passed to it, and we kept getting stack traces rendered into our CSS files. The stack trace was ruby looking for - and failing to find compass/reset.css.

This is the code that DOESN'T work (padrino 0.9.10, compass 0.8.17, sinatra 1.0).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  configure do
    register SassInitializer #The Rack Sass reloader...
 
    Compass.configuration do |config|
      config.project_path = File.dirname(__FILE__)
      config.sass_dir = "stylesheets"
      config.project_type = :stand_alone
      config.http_path = "/"
      config.css_dir = "stylesheets"
      config.images_dir = "images"
      config.output_style = :compressed
    end
  end   
  get '/stylesheets/:file.css' do
    content_type 'text/css', :charset => 'utf-8'
    # This is the doc on how to give Sass some more load paths to find the compass  files. 
    #   it doesnt work :P and for that matter, neither does:
    # sass :file, Compass.sass_engine_options
    # or the set :sass, whatever_hash_here
    sass :file, :sass => Compass.sass_engine_options
  end

Our solution was to force Sass options and Compass options to merge...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  configure do
    register SassInitializer
 
    Compass.configuration do |config|
      config.project_path = File.dirname(__FILE__)
      config.sass_dir = "stylesheets"
      config.project_type = :stand_alone
      config.http_path = "/"
      config.css_dir = "stylesheets"
      config.images_dir = "images"
      config.output_style = :compressed
    end
 
    Sass::Plugin.options.merge!(Compass.sass_engine_options)
  end
 
  get '/stylesheets/:file.css' do
    content_type 'text/css', :charset => 'utf-8'
    sass :file
  end

Yay, magic spells - it works. You can check out more ian magic spells at ianserlin.com.

Post to Twitter Post to Digg Post to Facebook Post to Reddit Post to StumbleUpon