NAME pervasives.rb SYNOPSIS access to pristine object state. if you don't metaprogram you probably don't need it INSTALL gem install pervasives URIS http://rubyforge.org/projects/codeforpeople/ http://codeforpeople.com/lib/ruby SAMPLES <========< samples/a.rb >========> ~ > cat samples/a.rb # # Pervasives allows objects' method to be accessed in a pristine state, even # when some effort has been made to derride them # require 'pervasives' class OpenStruct instance_methods.each{|m| undef_method m unless m[%r/__/]} def initialize @table = {} end def method_missing m, *a, &b case m.to_s when %r/[=]$/ @table[m.to_s.delete('=')] = a.shift when %r/[?!]$/ !!@table[m.to_s.delete('?!')] else @table[m.to_s] end end def inspect @table.inspect end end os = OpenStruct.new os.object_id = 42 os.send = 42 os.instance_eval = 42 p os p os.object_id p Pervasives.object_id(os) p os.send p Pervasives.send(os, "key=", "value") p os.instance_eval p Pervasives.instance_eval(os){ @table } ~ > ruby samples/a.rb {"instance_eval"=>42, "send"=>42, "object_id"=>42} 42 -609487514 42 "value" 42 {"instance_eval"=>42, "send"=>42, "key"=>"value", "object_id"=>42} <========< samples/b.rb >========> ~ > cat samples/b.rb # # sometimes it may be more convenient to use a Pervasives::Proxy object # insteand of using Pervasives directly # require 'pervasives' class BlankSlate instance_methods.each { |m| undef_method m unless m =~ /^__/ } def object_id() 42 end end bs = BlankSlate.new proxy = Pervasives::Proxy.new bs p bs.object_id p proxy.object_id ~ > ruby samples/b.rb 42 -609489100 <========< samples/c.rb >========> ~ > cat samples/c.rb # # the special '__' method accesses an object's Pervasives::Proxy # require 'pervasives' class BlankSlate instance_methods.each { |m| undef_method m unless m =~ /^__/ } def object_id() 42 end end bs = BlankSlate.new p bs.object_id p __(bs){ object_id } ~ > ruby samples/c.rb 42 -609486982 <========< samples/d.rb >========> ~ > cat samples/d.rb # # it all works for classes too # require 'pervasives' class C def self.new() raise end def inspect() 42 end end p( Pervasives.new(C) ) p( Pervasives::Proxy.new(C).new ) p( __(C).new ) ~ > ruby samples/d.rb 42 42 42