From: "David A. Black" Date: 2004-12-12T07:02:46+09:00 Subject: Re: Freezing Variable Assignment Hi -- On Sun, 12 Dec 2004, itsme213 wrote: > Leaving aside freezing local variables, I am curious what you think of > freezing controlled at the level of (the bindings of) individual Ruby > instance variables, rather than strictly for entire objects. So I can say > things like: > > class Home; def freeze ... end; end > myHome.freeze # cannot change door or door-knob, but can re-paint door > myHome.door = otherDoor #=> error > myHome.door.knob = otherKnob #=> error > myHome.door.color = otherColor #=> OK > > Today's Object#freeze can be implemented using this, I believe (extended to > deal with special cases for arrays, hashes, etc, and with the fact that > "freeze all instance variables, ... " in Ruby might mean prohibit dynamic > addition of new ivars). The converse is not true i.e. instance-variable > level freeze cannot be implemented using today's Object#freeze, and the > myHome example above is impossible to implement. It's not impossible -- you just have to do it by other means than Kernel#freeze. You'd want something called attr_freeze, that did something like: module AFreezer class FreezeError < TypeError # or whatever end def attr_freeze(*syms) c = (class << self; self; end) syms.each do |sym| c.class_eval do define_method("#{sym}=") { raise FreezeError } end end end end Then you could do: class Door include AFreezer attr_accessor :knob def freeze attr_freeze :knob end end and so on. (I have a longer, working example if you want to see it.) The fact that what you want to do is freezing-related and yet isn't going to piggyback on Kernel#freeze need not worry you in the slightest. Just use other techniques to achieve what you want. David -- David A. Black dblack@wobblini.net