using object(s) do ...
def using (*args) yield *args end
For (a rather half-assed) example:
>> using [10,20,30], 40 do |x,y| >> x << y if y.is_a? Fixnum >> puts x.to_s >> end 10203040 => nil
DZone Snippets > metaprogramming
11285 users tagging and storing useful source code snippets
Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world
def using (*args) yield *args end
>> using [10,20,30], 40 do |x,y| >> x << y if y.is_a? Fixnum >> puts x.to_s >> end 10203040 => nil
def with(object, &block) object.instance_eval(&block) end
numbers = [1, 2, 3] with numbers do map! { |n| n + 100 } reject! { |n| n % 2 == 0} end p numbers # => [101, 103] n = 15 n = with n do self + 13 end p n # => 28
module JCV def self.included(the_class) class << the_class def acts_like_java_class_variable( *arg) the_class = self singleton_class = class << self; self; end arg.each do |var| singleton_class.send :define_method, "#{var}", & lambda{ the_class.send "__real_#{var}"} singleton_class.send :define_method, "#{var}=", & lambda{|c| the_class.send "__real_#{var}=",c} singleton_class.send :define_method, "__real_#{var}", & lambda{ instance_variable_get "@#{var}"} singleton_class.send :define_method, "__real_#{var}=", & lambda{|c| instance_variable_set "@#{var}", c} end end end end end class A include JCV acts_like_java_class_variable :count @count = 0 def initialize A.count +=1 end end
virtual_class = class <<obj; self; end virtual_class.class_eval { obj.methods.each { |method| the_alias = method.gsub(/([^?]+)(\??)/, "\\1_orig\\2").to_sym alias_method the_alias, method define_method(method) { |*args| args_str = args.map { |a| a.inspect }.join(", ") unless method == "to_s" puts "#{self.inspect_orig}.#{method}(#{args_str}) called from #{caller.inspect}" end self.send_orig(the_alias, *args) } } }
module AttributeCache def metaclass; class << self; self; end; end def cache(attr_name, options) instance_variable_set "@#{attr_name}", options[:initial] instance_variable_set "@#{:sum}_outdated", true metaclass.instance_eval do define_method("outdate_#{attr_name}") do puts "in outdated" instance_variable_set "@#{attr_name}_outdated", true end end metaclass.class_eval %Q{ def cached_#{attr_name}(&block) if @#{attr_name}_outdated puts "in cached to update!" @#{attr_name}_outdated = false @#{attr_name} = block.call else puts "in cached to give cache!" end return @#{attr_name} end } end end class Collection include AttributeCache def initialize @array = [] cache :sum, :initial => 0 end def add(x) outdate_sum @array << x end def sum cached_sum { @array.inject {|t, e| t += e} } end end c = Collection.new puts c.public_methods(false).inspect c.add(2) c.add(3) puts c.sum puts c.sum c.add(4) puts c.sum puts c.sum
class Object def self.__rules__ # container for defined rules, each item is: # [class, event_name, method_name, alias_for_original_method, caller, comment] @@rules ||= [] end def self.__create_rule_instead( method, comment = '', &block) # creates and returns new rule b_id = "%04x" % block.object_id old_method_name = :"__previous_#{method}_#{b_id}" alias_method old_method_name, method define_method method, &block __rules__ << rule = [self, "INSTEAD", method, old_method_name,caller[0], comment ] rule end def self.__create_rule_before( method, comment = '', &block) args = instance_method(method).arity == 0 ? '' : '(*args)' b_id = "%04x" % block.object_id old_method_name = :"__previous_#{method}_#{b_id}" alias_method old_method_name, method define_method :"__before_#{method}_#{b_id}", &block class_eval <<-EOT def #{method}#{args} __before_#{method}_#{b_id}#{args} __previous_#{method}_#{b_id}#{args} end EOT __rules__ << rule = [self, "BEFORE", method, old_method_name, caller[0], comment] rule end def self.__create_rule_after( method, comment = '', &block) args = instance_method(method).arity == 0 ? '' : '(*args)' b_id = "%04x" % block.object_id old_method_name = :"__previous_#{method}_#{b_id}" alias_method old_method_name, method define_method :"__after_#{method}_#{b_id}", &block class_eval <<-EOT def #{method}#{args} res = __previous_#{method}_#{b_id}#{args} __after_#{method}_#{b_id}#{args} res end EOT __rules__ << rule = [self, "AFTER", method, old_method_name,caller[0], comment ] rule end def self.__remove_rule( rule ) # has some bugs when rules on subclasses are defined :( idx = __rules__.index(rule) if idx # look for next rule for the same method idx += 1 while idx < __rules__.size break if __rules__[idx][2] == rule[2] && __rules__[idx][0] == rule[0] idx+=1 end if idx < __rules__.size next_rule = __rules__[idx] next_rule[0].send :remove_method, next_rule[3] next_rule[0].send :alias_method, next_rule[3], rule[3] else # that was last rule[0].send :remove_method, rule[2] rule[0].send :alias_method, rule[2], rule[3] end __rules__.delete(rule) end end end
class Model def save puts "save" end def reload(flag) "reloaded" end end r1 = Model.__create_rule_instead(:reload) {|flag| flag ? "FRESH" : "STALE" } obj = Model.new puts "RELOAD:"+obj.reload(true) puts "RELOAD:"+obj.reload(false) Object.__remove_rule(r1) puts "RELOAD:"+obj.reload(false) Model.__create_rule_before(:save) { puts "BEFORE SAVE" } r2 = Model.__create_rule_before(:save) { puts "YET BEFORE SAVE" } Model.__create_rule_after(:save) { puts "AFTER SAVE" } r3 = Model.__create_rule_after(:save) { puts "YET AFTER SAVE" } obj.save Object.__remove_rule(r2) puts "----------" obj.save Object.__remove_rule(r3) puts "----------" obj.save
RELOAD:FRESH RELOAD:STALE RELOAD:reloaded YET BEFORE SAVE BEFORE SAVE save AFTER SAVE YET AFTER SAVE ---------- BEFORE SAVE save AFTER SAVE YET AFTER SAVE ---------- BEFORE SAVE save AFTER SAVE
class ActiveRecord::Base def self.pretty_conditions(hash) meta_def hash[:name] do array = [] puts "#{hash[:message]}:" puts "------------------" self.find(:all, :conditions => hash[:conditions]).each do |record| module_eval %[puts record.#{hash[:column_name]}] array << record end puts "------------------" puts "Total: #{array.size}" puts "------------------" end end end
class Youth < ActiveRecord::Base pretty_conditions :name => 'unsponsored', :column_name => 'name', :message => "Unsponsored Youth", :conditions => "sponsor LIKE '%XXX%'" pretty_conditions :name => 'touchgroup_leaders', :column_name => 'name', :message => "Touchgroup Leaders", :conditions => ["touchgroup =?",'t'] pretty_conditions :name => 'vegitarians', :column_name => 'name', :message => "Vegitarians", :conditions => ["vegitarian =?",'t'] end Youth.unsponsored Youth.touchgroup_leaders Youth.vegitarians
saurasaurusrex:~/software cdcarter$ ruby actions.rb Unsponsored Youth: ------------------ Hannah Gilbert Jesse Lavercombe Zach Adams Danika Zabertini ------------------ Total: 4 ------------------ Touchgroup Leaders: ------------------ Leland McKeeman Marlee Leebrick-Stryker Meggie Huges-Morrison ------------------ Total: 3 ------------------ Vegitarians: ------------------ Marlee Leebrick-Stryker Meggie Huges-Morrison Amelia Nybakke Ethan Edl Maggie Heath ------------------ Total: 5 ------------------
# Example: # # class Test1 # include Overload # # def foo # puts "foo # Original one" # end # # overload :foo, :foo_str, String do |str, x| # puts "foo_str(String str, x)" # end # # overload :foo, Integer do |i| # puts "foo(Integer i) # no specific name" # end # end module Overload def self.included(klass) class << klass include Overload::Feature end end def self.spec_to_cond(spec) code = "args.length == #{spec[0]}" spec[1..-1].each_with_index { |s, i| code << " && #{s.inspect} === args[#{i}]" } code end module Feature private def overload(method_id, *spec, &block) if spec[0].instance_of? Symbol specific_method_id = spec.shift define_method(specific_method_id, block) if block block = instance_method(specific_method_id) elsif block define_method(method_id, block) block = instance_method(method_id) remove_method(method_id) else raise "You must give a block or a name of existing method!" end spec.unshift(block.arity) add_method_to_dispatch_table(method_id, spec, block) update_dispatcher(method_id) end def add_method_to_dispatch_table(method_id, key, block) if !dispatch_table[method_id] dispatch_table[method_id] = Hash.new end dispatch_table[method_id][key] = block end def update_dispatcher(method_id) remove_method(method_id) if method_defined?(method_id) class_eval dispatcher_code(method_id), "#{method_id}_dispatcher", 0 end def dispatcher_code(method_id) method_body = <<-EOS def #{method_id.to_s}(*args, &blk) dt = DispatchTable[#{method_id.inspect}] EOS sorted_dispatch_table_of(method_id).each_with_index do |(spec, block), i| method_body << <<-EOS #{(i==0) ? "if" : "elsif"} #{Overload::spec_to_cond(spec)} dt[#{spec.inspect}].bind(self).call(*args, &blk) EOS end method_body << <<-EOS else raise "Couldn't find method for #{method_id}(\#{args.inspect[1..-2]})" end end EOS end def sorted_dispatch_table_of(method_id) dispatch_table[method_id].sort do |a,b| a[0].length <=> b[0].length end end def dispatch_table const_set("DispatchTable", Hash.new) if !const_defined?("DispatchTable") const_get("DispatchTable") end end end
def method_name if /`(.*)'/.match(caller.first) return $1 end nil end def blah puts method_name end blah # => 'blah'
agent_name = "#{model_name.to_s.camelize}Agent" agent_class = instance_eval %{Object::#{agent_name} = Class.new(Administration::Agent)}
agent_name_pieces = agent_name.split('::') agent_class_name = agent_name_pieces.pop agent_module = agent_name_pieces.inject(Object) { |obj, name| obj.const_defined?(name) ? obj.const_get(name) : obj.const_set(name, Module.new) } agent_class = agent_module.const_set(agent_class_name, Class.new(Administration::Agent))