Pervasives-0.0.1


#1

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

enjoy and send in yer comments/patches!

-a


#2

removed_email_address@domain.invalid wrote:

enjoy and send in yer comments/patches!

is this perhaps impossible b/c of callbacks? since any dot magic DSL is
created via method_missing how can we possibley remove all the methods
including #method_missing? and if we’re stuck with one exception, what
does a half-dozen more really make (just so long as they have uncommon
names)?

t.


#3

removed_email_address@domain.invalid wrote:

enjoy and send in yer comments/patches!

_ = Pervasives

_.send(obj, message)

T.


#4

On 1/6/07, Trans removed_email_address@domain.invalid wrote:

removed_email_address@domain.invalid wrote:

enjoy and send in yer comments/patches!

_ = Pervasives

_.send(obj, message)

Ooh. I think that at least in the context of this lib, that’s
reasonable enough.

Surely concise


#5

On Sat, 6 Jan 2007, Trans wrote:

removed_email_address@domain.invalid wrote:

enjoy and send in yer comments/patches!

_ = Pervasives

_.send(obj, message)

yeah - i thought about that, but i use ‘_’ often in loops like

hash.map{|k,_| k.upcase}

when i plan to ignore a block param.

cheers.

-a


#6

On 1/6/07, removed_email_address@domain.invalid removed_email_address@domain.invalid wrote:

yeah - i thought about that, but i use ‘_’ often in loops like

hash.map{|k,_| k.upcase}

when i plan to ignore a block param.

Hmm, also a good tip Ara, neat.


#7

removed_email_address@domain.invalid wrote:

NAME

pervasives.rb

SYNOPSIS

access to pristine object state. if you don’t metaprogram you probably
don’t need it
[snip]
enjoy and send in yer comments/patches!

well, of course i think it’s great that you took the time to do this.
but i’m afraid i have an unfortunate little story to tell you.

you see about a year ago i was working on my BasicObject implementation
and how to deal with this exact problem. if you recall i brought up
this very thing on ruby-talk. i had implemented my own version of
Pervasives – i beleive it was call Meta and/or Inspect at first, but i
later realized the methods fit well in ObjectSpace. tied to this I
created a shortcut to these mthod via a proxy like yours but rather
than ‘(obj).foo’, mine was 'obj..foo.’. Hey, great mind think
alike! :slight_smile:

now the tragic ending… with my new lib in hand i went about reworking
my meta code with it. well, it wasnt too long after that i realized it
sucked. my meta-code become bloated, harder to read and slower – it
just wasn’t worth it. and so i gave up on it.

so that’ my little story and i fear the same will happen for you. i
think if the issue is going to be truly addressed, we need to work on
something more fundamental. btw eventually i just settled on using
object_class and object_send aliases when need be (shadow methods
class, send, etc. just got on my nerves) and lived with the
over-ride imperfections.

T.