class Object # Includes a module into the current Class, and changes all the module's public methods to protected. # # Example: # class FooController # safely_include_module(MyCoolUtils, MyOtherModule) # end def safely_include_module(*modules) [modules].flatten.each do |mod| mod.include_safely_into(self) end end # Prints out the methods associated with this object in alphabetical order. def print_methods m = "----- #{self} (methods) -----\n" m << methods.sort.join("\n") puts m m end # An elegant way to refactor out common options # # with_options :order => 'created_at', :class_name => 'Comment' do |post| # post.has_many :comments, :conditions => ['approved = ?', true], :dependent => :delete_all # post.has_many :unapproved_comments, :conditions => ['approved = ?', false] # post.has_many :all_comments # end # # Can also be used with an explicit receiver: # # map.with_options :controller => "people" do |people| # people.connect "/people", :action => "index" # people.connect "/people/:id", :action => "show" # end # def with_options(options) yield Mack::Utils::OptionMerger.new(self, options) end # See Class parents for more information. def class_parents self.class.parents end # This method gets called when a parameter is passed into a named route. # This can be overridden in an Object to provlde custom handling of parameters. def to_param self.to_s end # Uses define_method to create an empty for the method parameter defined. # That method will then raise MethodNotImplemented. This is useful for creating interfaces # and you want to stub out methods that others need to implement. def self.needs_method(meth) define_method(meth) do raise NoMethodError.new("The interface you are using requires you define the following method '#{meth}'") end end # This prints out running time for the block provided. This is great for things # like Rake tasks, etc... where you would like to know how long it, or a section of # it took to run. def running_time(message = "", logger = nil) s_time = Time.now s = "---Starting at #{s_time}---" puts s logger.info s unless logger.nil? yield if block_given? e_time = Time.now e = "---Ending at #{e_time}---" puts e logger.info e unless logger.nil? secs = e_time - s_time if secs < 60 x = "Running time #{secs} seconds." else x = "Running time roughly #{secs/60} minutes [#{secs} seconds]" end x += " [MESSAGE]: #{message}" unless message.blank? puts x logger.info x unless logger.nil? end # This method will call send to all the methods defined on the previous method. # # Example: # Fruit.send_with_chain([:new, :get_citrus, :get_orange, :class]) # => Orange # # This would be the equivalent: # Fruit.new.get_citrus.get_orange.class def send_with_chain(methods, *args) obj = self [methods].flatten.each {|m| obj = obj.send(m, *args)} obj end # ivar_cache allows you to cache the results of the block into an instance variable in a class, # and then will serve up that instance variable the next time you call that method again. # # old way: # def show_page_link # unless @show_page_link # check if instance variable exists # # if the instance variable doesn't exist let's do some work and assign it to the instance variable. # @show_page_link = link_to("show", some_url(:id => self.id, :foo => bar, etc... => etc)) # end # @show_page_link # now return the instance variable # end # # new way: # def show_page_link # ivar_cache do # link_to("show", some_url(:id => self.id, :foo => bar, etc... => etc)) # end # end # # this does everything the old way did, but it is much cleaner, and a lot less code! # in case you're wondering it caches the result, by default, to an instance variable named after the method, # so in our above example the instance variable would be name, @show_page_link. this can be overridden like such: # # def show_page_link # ivar_cache("foo_var") do # link_to("show", some_url(:id => self.id, :foo => bar, etc... => etc)) # end # end # # now it will cache it to @foo_var def ivar_cache(var_name = nil, &block) if var_name.nil? call = caller[0] var_name = call[(call.index('`')+1)...call.index("'")] end var = instance_variable_get("@#{var_name}") unless var return instance_variable_set("@#{var_name}", yield) if block_given? end instance_variable_get("@#{var_name}") end def ivar_cache_clear(var_name = nil, &block) if var_name.nil? call = caller[0] var_name = call[(call.index('`')+1)...call.index("'")] end remove_instance_variable("@#{var_name}") #rescue yield if block_given? end # Returns the namespaces for a particular object. # # Examples: # Animals::Dog::Poodle.new.namespaces # => ["Animals", "Dog"] def namespaces ivar_cache("object_namespaces") do nss = [] full_name = self.class.name.to_s nss = full_name.split("::") nss.pop nss end end end