From: ara.t.howard@... Date: 2007-01-19T00:43:01+09:00 Subject: Re: Hash#open! / Hash#close! On Thu, 18 Jan 2007, Trans wrote: > hi-- > > have a look: > > class Hash > > def open! > class << self > @_were_public = public_instance_methods - ['close!'] > @_were_public.each { |m| private m } > def method_missing(s,*a) > if s.to_s[-1,1] == '=' > self[s] = a.first > else > return self[s] > end > end > end > end > > def close! > class << self > @_were_public.each { |m| public m } > @_were_public = nil > remove_method(:method_missing) > end > end > > end > > usage: > > h = {a=>1, :sort_by=>2} > h.a #=> NoMethodError > h.sort_by #=> LocalJumpError > h.open! > h.a #=> 1 > h.sort_by #=> 2 > h.close! > h.a #=> NoMethodError > h.sort_by #=> LocalJumpError > > thoughts? improvements? useful? bad-news? > > T the only real disadvantage i see is that all these find_all keys []= each object_id singleton_methods inject delete value? to_hash equal? taint sort_by frozen? instance_variable_get max kind_of? each_pair respond_to? to_a delete_if merge! index select merge length type partition protected_methods store grep eql? instance_variable_set hash is_a? values reject to_s send default class size tainted? private_methods __send__ member? default= default_proc untaint find each_with_index reject! id invert instance_eval collect inspect has_key? replace all? == === indexes entries clone public_methods extend each_value fetch detect freeze values_at zip display update __id__ shift method has_value? empty? map =~ methods clear any? rehash nil? sort dup indices key? min instance_variables include? [] instance_of? each_key cannot be keys since method_missing is use to set the key. an impl like this could get around that harp:~ > cat a.rb class Hash class Proxy alias_method '__instance_eval__', 'instance_eval' instance_methods.each{|m| undef_method m unless m[/__/]} def initialize h, &b @h = h __instance_eval__ &b if b end def method_missing m, *a, &b k = m.to_s.delete '=!?' case a.size when 0 @h[k] when 1 @h[k] = a.shift else @h[k] = a end end end def open! &b proxy = Proxy.new self, &b b ? self : proxy end end h = { 'k' => 'v' } p h h.open!{ k 42 } p h h.open!{ self.a = 42.0 } p h proxy = h.open! proxy.b = 'forty-two' p h h.open!{ sort 'can_be_set' } p h harp:~ > ruby a.rb {"k"=>"v"} {"k"=>42} {"k"=>42, "a"=>42.0} {"k"=>42, "a"=>42.0, "b"=>"forty-two"} {"k"=>42, "a"=>42.0, "b"=>"forty-two", "sort"=>"can_be_set"} neat idea though. -a -- in the practice of tolerance, one's enemy is the best teacher. - the dalai lama