NAME
pervasives.rb
SYNOPSIS
access to pristine object state. if you don't metaprogram or write
debuggers you probably don't need it.
INSTALL
gem install pervasives
URIS
http://rubyforge.org/projects/codeforpeople/
http://codeforpeople.com/lib/ruby
HISTORY
1.1.0
added Pervasives.call method, refactored a bit, updated samples, updated
tests for new api
1.0.0
is NOT backward compatible with any other pervasives version. the new
library is __greatly__ simplified
SAMPLES
<========< samples/a.rb >========>
~ > cat samples/a.rb
#
# Pervasives allows an object's methods to be accessed in a pristine state,
# even when some effort has been made to derride them
#
require 'pervasives'
class BlankSlate
instance_methods.each{|m| undef_method m unless m[%r/__/]}
end
bs = BlankSlate.new
p Pervasives(bs).methods #=> ["__object_pervasive__", "__id__", "__send__", "__pervasive__"]
p Pervasives(bs).is_a?(BlankSlate) #=> true
p Pervasives(bs).instance_eval{ @a = 42 } #=> 42
p Pervasives(bs).instance_variables #=> ["@a"]
~ > ruby samples/a.rb
["__pervasive__", "__id__", "__send__"]
true
42
["@a"]
<========< samples/b.rb >========>
~ > cat samples/b.rb
#
# the special method __pervasive__ is added to all objects - it can be used to
# access the pristine state
#
require 'pervasives'
class C
def instance_eval(*a, &b) raise end
end
c = C.new
c.__pervasive__(:instance_eval){ @a = 42 }
p c.instance_variables #=> ["@a"]
~ > ruby samples/b.rb
["@a"]
<========< samples/c.rb >========>
~ > cat samples/c.rb
#
# even if hackery removes the __pervasive__ method you can still call a
# pristine method on an object
#
require 'pervasives'
class VeryBlankSlate
instance_methods.each{ |m| undef_method m }
end
vbs = VeryBlankSlate.new
begin
vbs.__pervasive__
rescue
'nope not even that'
end
Pervasives.call(vbs, :instance_eval){ @a = 42 }
p Pervasives.call(vbs, :instance_variables) #=> ["@a"]
~ > ruby samples/c.rb
samples/c.rb:8: warning: undefining `__id__' may cause serious problem
samples/c.rb:8: warning: undefining `__send__' may cause serious problem
["@a"]
<========< samples/d.rb >========>
~ > cat samples/d.rb
#
# of course it works for classes and modules too
#
require 'pervasives'
class C
def self.new() raise end
def inspect() 42.inspect end
end
c = C.__pervasive__ :new
p c #=> 42
~ > ruby samples/d.rb
42