On 18.01.2007 14:12, 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?

What's the advantage over an OpenStruct?

irb(main):001:0> h = OpenStruct.new(:a=>1, :sort_by=>2)
=> #<OpenStruct sort_by=2, a=1>
irb(main):002:0> h.a
=> 1
irb(main):003:0> h.sort_by
=> 2

I'd probably rather make the logic from OpenStruct's constructor 
available as update or merge method.  But this is just a gut feeling.

> ps. i came across an oddity while messing with this:
> 
> irb(main):019:0> q = {}
> => {}
> irb(main):020:0> q.sort_by
> => []
> irb(main):021:0> q[:a] = 1
> => 1
> irb(main):022:0> q.sort_by
> LocalJumpError: no block given
>         from (irb):22:in `sort_by'
>         from (irb):22
>         from :0
> ruby 1.8.4 on debian

Same for Array.  Not a big deal IMHO because the extra overhead of 
checking for the block makes the average case (sorting non empty 
collections) slower.

Kind regards

	robert