Nathan Wiger wrote:
> 
> > I think such modules are a bad idea, because their functionality is
> > typically restricted.
> 
> What, you mean like CGI.pm ?! :-)

Yes, restricted.  If you use the procedural interface to a module that
supports both OO and procedural interfaces, you're basically at the
mercy of all other modules in your program, becuase they easily screw it
up for you.

Look, there's a reason we have objects - they encapsulate state.  If a
module supports objects and procedural calls, in the latter case it will
either need a handle to the state (objects by anoither name), or will
store the state internally.  If the module stores the state internally,
then you can only have one active caller at a time.  If another module
also uses the procedural interface, and also expects to be the only
user, things break.

Obviously this is not a big problem with CGI.pm, as it represents global
state and you typically don't have modules calling into it, but it is a
real problem with modules not representing global state.

> 
> To get off the religion point for a second, one thing that hasn't been
> discussed but which I've been pondering heavily is the ability to
> backtrace contexts like caller(). Consider how this could be used to go
> up levels of chained object calls:
> 
>     Apache->request->uri;
>    caller(1) caller(0)
>     self(1)   self(0)
> 
> That is, self(0) (or just "self") would give you a reference pointing to
> the object produced by Apache->request, whereas self(1) would give you a
> reference to the original Apache class.
> 
> Consider how useful this would be in chained fileobject calls:
> 
>    open("</etc/motd")->dup->readline;
>        self(1)        self(0)
> 
> Here, self(0) would give you a reference to the dup'ed filehandle, and
> self(1) would give you a reference to the original one.

This is extremely dangerous and generally should not be done.  In this
case, a method is dependent on being invoked in another way.  Let's take
your example.

 open("</etc/motd")->dup->readline;

If I now need to read two lines, a reasonable code transformation would
be:

  my $dup = open("</etc/motd")->dup();
  for (1..2) { $dup->readline(); }

And now, suddenly, the readline() method breaks, because it doesn't have
two levels of caller.

There's a reason methods stand alone - that's becuase they should be
generally usable in different circumstances.

Hildo

Reply via email to