From: Keith Hodges Date: 2001-07-12T23:36:55+09:00 Subject: [ruby-talk:17721] Null Pattern This is a multi-part message in MIME format. --------------041919C8BED3568C788FBB05 Content-Type: multipart/alternative; boundary="------------72FABD2BB1DD20D53F6D2AF7" --------------72FABD2BB1DD20D53F6D2AF7 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Keith Hodges wrote: > Has anyone implemented the Null pattern in ruby yet? > > I am giving it a go, but its the kind of thing that has lots of subtle implications. > > thanks in advance > > Keith Well I have made some progress, but I have some questions that people might be able to help me with. Q.1 What is the best way to define a new global constant like "nil" (i.e. lowercase). My first attempt is as follows, but I have a feeling there should be something better. NULL=Null.new def null NULL end Q.2 I would like to be able to obtain information about the instanciator of aNull so far I have found Kernal#binding and Kernal#caller but I cant find out how to use these to get the information that I want, which is "Object, and method that instanciated me." Q.3 given the code below is there a way to exit a call chain as follows a=null a.nice.way.to.avoid.testing.for.nil.all.of.the.time #I want to get as fast as possible! at present my implementation of Null#method_missing returns self. This means that the code above calls Null#method_missing on each "undefined message eating null" method call, 11 times! what I was wondering is whether there is a way to jump from a.nice (implemented by Null#method_missing) to in a quick and elegant manner (i.e. like a throw catch but without the semantics) ---- thanks in advance, Keith --------------72FABD2BB1DD20D53F6D2AF7 Content-Type: text/html; charset=us-ascii Content-Transfer-Encoding: 7bit Keith Hodges wrote:
Has anyone implemented the Null pattern in ruby yet?

I am giving it a go, but its the kind of thing that has lots of subtle implications.

thanks in advance

Keith

Well I have made some progress, but I have some questions that people might be able to help me with.

Q.1 What is the best way to define a new global constant like "nil" (i.e. lowercase).

My first attempt is as follows, but I have a feeling there should be something better.

NULL=Null.new
def null
    NULL
end

Q.2 I would like to be able to obtain information about the instanciator of aNull
so far I have found Kernal#binding and Kernal#caller but I cant find out how to use these to get
the information that I want, which is "Object, and method that instanciated me."

Q.3 given the code below is there a way to exit a call chain as follows

a=null
a.nice.way.to.avoid.testing.for.nil.all.of.the.time
#I want to get <HERE> as fast as possible!

at present my implementation of Null#method_missing returns self. This means that the code above calls Null#method_missing on each "undefined message eating null" method call, 11 times!

what I was wondering is whether there is a way to jump from a.nice (implemented by Null#method_missing) to <HERE> in a quick and elegant manner (i.e. like a throw catch but without the semantics)

----

thanks in advance,

Keith
 
 
 
 
 
 
  --------------72FABD2BB1DD20D53F6D2AF7-- --------------041919C8BED3568C788FBB05 Content-Type: text/plain; charset=us-ascii; name="Null.rb" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="Null.rb" #!/usr/bin/env ruby #This is a first attempt at supporting the Null pattern in Ruby #I couldnt find a detailed explanation of the Null pattern on the web #so this is a cleanroom implementation and there are probably things #I have forgotton class Null attr_reader :name attr_reader :theCaller attr_reader :theBinding def initialize(aString='') @name = aString @theCaller = caller @theBinding = binding end def debug @debug=true if (name.size > 0) self end def isDefaultNull? self === NULL end def null? true end def nil? true end def ==( a ) a.nil? end def new( *args ) Null.new( *args ) end def to_s return 'NULL' if isDefaultNull? 'null' + @name end def method_missing( aSymbol, *args ) puts("XX-" + theCaller.join("\n") + aSymbol.to_s + "-XX" ) if (@debug == true) self end def respond_to? true end def hash nil.hash end end class Object def null? false end end #allows users to refer to "null" #or a named null('') NULL=Null.new def null( *args ) return(NULL) if (args.size == 0) return(Null.new(*args)) end --------------041919C8BED3568C788FBB05--