On Thu, 14 Nov 2002 05:10:40 +0900, Joel VanderWerf wrote:
> Austin Ziegler wrote:
>> Dave & Andy also noted that you can make it so that initialize
>> receives a block. Lyle recently implemented a change to the
>> FXRuby code that makes the technique cleaner (in that you don't
>> have to use 'self' all over the place), like so:

[ruby-talk:55739]

> Cleaner, maybe, but there is a tradeoff. Both @name and @age must
> have writers for the above to work. With the other approach (block
> is handled with instance_eval), you can write:

<snip>

> Either way, you're breaking encapsulation--by exposing writers, or
> by exposing the attrs themselves at the time of construction
> (only).

You're right, and in some cases, that's OK (see Text::Format for
this; I haven't yet modified it to use Lyle's change -- I may not),
since all of the methods are exposed anyway.

Alternatively, using a semi-combination of the two methods, you can
use otherwise private methods (see MIME::Types::Type for an example
of this). (Interestingly, it does NOT seem to work with
attr_accessor, but if I manually define name= as private, it works.)

Text::Format has an initializer which can act as a copy constructor
(accepting another Text::Format), with a Hash (using string names,
not symbols; that's not too hard a change to make, though), a
String, and no argument -- and all forms accept a block for further
customization. Text::Format by default exposes the @varname form; it
will probably be changed to allow what Lyle does.

MIME::Types::Type has an initializer which can act as a copy
constructor, with an Array, a a Hash, or a String. It too, accept
blocks. It doesn't allow assignment after creation, so it has some
private functions that can only be called from within the
constructor (and it's documented as such).

I think I may submit an RCR for instance_eval to be modified such
that there is a way to specify what can/will be yielded to the block
given.

-austin
-- Austin Ziegler, austin / halostatue.ca on 2002.11.13 at 15.24.26