in reply to What is this can() and why is breaking it (un)acceptable? in thread Why breaking can() is acceptable
Quite simply, all classes in perl inherit from UNIVERSAL. UNIVERSAL implements can. Your class then has an obligation (IMO of course) to provide a working version of can in its interface. If you break aspects of your base class in your subclass you are doing bad OO and defeating the whole purpose of re-use through inheritance.
-stvn
Re: Re: What is this can() and why is breaking it (un)acceptable?
by hardburn (Abbot) on Apr 06, 2004 at 16:58 UTC
|
Your class then has an obligation (IMO of course) to provide a working version of can in its interface.
If we are talking from an OO purity point of view, I would agree. Anything that breaks inheritance is evil and must be avoided.
OTOH, a lot of people agree that multiple inheritance is needed in some cases, but there is no good way to implement it. How do you handle dimand inheritance? In what order do you call destructors (something that's been an issue on the Squawks of the Parrot blog of late)? There's no good answer, and an awful lot of bad ones.
Abigail-II gave a great example in this thread of how easy it is to break inheirtance in Perl (one which I hadn't considered before). If you implement your class as a hashref, all your parents and subclasses also must use a hashref. Which might be the most common case, but it isn't the only one.
Observation: this thread is a case study in why Perl's object system is hacked on.
----
: () { :|:& };:
Note: All code is untested, unless otherwise stated
| [reply] [d/l] |
Re: What is this can() and why is breaking it (un)acceptable?
by jonadab (Parson) on Apr 07, 2004 at 04:00 UTC
|
Quite simply, all classes in perl inherit from UNIVERSAL. UNIVERSAL implements can.
This is an interesting statement. The index of my
Camel book (2nd ed) does not list can at all and
contains only one entry for UNIVERSAL, which points
to page 293, where I find the following quote
(emphasis mine):
If neither a method nor an AUTOLOAD routine
is found in @ISA, then one last, desperate try is
made for the method (or an AUTOLOAD routine) in the
special predefined class called UNIVERSAL.
This package does not initially contain any
definitions (although see CPAN for some), but
you may place your "last-ditch" methods there.
This not only doesn't support your assertion but
seems on the face of it to directly contradict what
you were saying. How can UNIVERSAL implement can,
and require that all derived objects (i.e., all
objects) not break that, if UNIVERSAL does not
initially contain any definitions? Further,
NOTHING is said here about any obligations that any
module has to provide or support any particular
method.
Granted, what I have is not the latest edition, but
none of the reviews I have read of the third edition
have said anything about the new edition containing
important information about fundamental changes to
the language that every Perl programmer must know,
nor is it advertised that way by the author or by
the publisher. It's simply the next edition of the
book, no more.
I did see some reviews praising the addition of
numerous new examples, but nothing that seemed to
indicate to me that if I program according to the
second edition I'll break things. To be perfectly
honest, I've got a lot of things marked in my camel
(not least, little tabs on the sides of the pages
to mark where certain sections start so I can quickly
flip e.g. to the section on special variables), and
not wanting to redo all of that right away I was
going to wait for the fourth edition, which hopefully
will cover Perl6, before upgrading. Perhaps you
could quote me just the paragraph of the 3rd edition
that explains why every object is required to
support the can method.
update: In the light of morning,
the next paragraph seems harsh to me. I didn't
mean it that way. I'm not going to edit it out,
though, because the reply wouldn't make (as much)
sense then. (And chromatic, I recognize your
reputation, but you hadn't yet come out to say
anything in the thread when I wrote this.)
I'm interested in hearing about the merits of can,
the practical reasons why it's a useful thing for
modules to support, even if the module author does
not personally use it. I'm somewhat less interested
in hearing you just tell me (in so many words)
"This is just required". I might accept
that coming from someone who is on a first-name basis
with Larry's wife, but I am dubious as to what
authority you have to make
up requirements for all Perl modules to adhere to.
;$;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}}
split//,".rekcah lreP rehtona tsuJ";$\=$;[-1]->();print
| [reply] |
|
jonadab
To start with, your Camel book is out of date, but thankfully, http://www.perldoc.com is not. Here is a link to the UNIVERSAL page. You may find this enlightening.
As for my opinion (and I did make a point to say it was my opinion (note the "IMO")) about OO module designers obligations (please keep in mind it is specific to OO modules, as only blessed references inherit from UNIVERSAL). They are my opinions, you and the whole of the perl community have every right to dismiss them as the ravings of a lunatic (believe you wouldn't be the first).
But my assertion that it is bad OO design to break the a method in your base class through some fault of your subclass, actually has nothing (directly) to do with Perl at all. It is just OO design, sure its maybe strict OO design, which Perl is certainly not known for, but if you pick up any (good) book on the subject, I am sure you will find something similar to what I say.
-stvn
| [reply] |
|
your Camel book is out of date, but thankfully, http://www.perldoc.com is not.
If I start using online docs, I'm going to
end up wanting to
keep every system up to date with the latest perl
all the time. I was hoping to avoid that until
Perl6 comes out. At present I use systems that have
everything ranging from 5.005 through 5.6.1 to 5.8.1,
and this has never proven to be a problem, not
even when using a lot of modules off of the CPAN.
I wouldn't want to start relying on all the latest
features; that would be bad design for sure, and
not only in terms of OO purity.
In retrospect, my other post seems to have come
across as a little harsh. For that I'm sorry.
But I disagree that it's bad design to break
something that's a fairly new feature anyway,
within the same major version (Perl5).
;$;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}}
split//,".rekcah lreP rehtona tsuJ";$\=$;[-1]->();print
| [reply] |
|
|