From: Tim Hunter Date: 2006-03-21T22:34:00+09:00 Subject: Re: Initializing ivars from block without prefixing with self? Dave Baldwin wrote: > I am creating a DSL using Ruby. A cut down version is below: > > class _Box > attr_accessor :width > > def initialize (&block) > self.width = 20 # some default value > instance_eval(&block) if block_given? > end > end > > # Helper function to avoid the DSL user having to use .new > def Box(&block) > _Box.new(&block) > end > > I want to do something like: > > Box {width = 10} > > but the only way I can get it to work is > > Box {self.width = 10} > > Having to prefix the ivar with self. makes the DSL look clunky and > wouldn't be acceptable to my users. > > Is there anyway to avoid the self.? Using {@width = 10} will work but > prevents some necessary validation from taking place. > > > I have an alternative where width is a method: > > class _Box > def width (val = :no_param) > if val != :no_param > @width = val > end > @width > end > end > > so with this I can write > > Box {width 10} > > which is acceptable from the DSL view point, but makes the getter > operations more expensive. In the real version a getter operation > takes about 7 statements to allow for evaluation of block if the ivar > had been set to a Proc object and inheritance of values from its parent > object (in a visual hierarchy). The setter operation is often only > done when the object is created but the getter is done very frequently > so I want to move down the route of separate setters and getters rather > than combining them in the one method as an optimization. > > Dave. > > > Good article on DSLs and addresses your question: http://www.artima.com/rubycs/articles/ruby_as_dsl.html