[32618] in Perl-Users-Digest
Perl-Users Digest, Issue: 3892 Volume: 11
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Tue Mar 5 14:09:18 2013
Date: Tue, 5 Mar 2013 11:09:04 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Tue, 5 Mar 2013 Volume: 11 Number: 3892
Today's topics:
getting perl and php to talk to each other, was Re: ra <cal@example.invalid>
Re: getting perl and php to talk to each other, was Re <sorry_no_mail_here@nowhere.dee>
Re: some random remarks about Moose::Manual::Concepts <rweikusat@mssgmbh.com>
Re: some random remarks about Moose::Manual::Concepts <ben@morrow.me.uk>
Re: some random remarks about Moose::Manual::Concepts <ben@morrow.me.uk>
Re: some random remarks about Moose::Manual::Concepts <rweikusat@mssgmbh.com>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Tue, 05 Mar 2013 01:19:16 -0800
From: Cal Dershowitz <cal@example.invalid>
Subject: getting perl and php to talk to each other, was Re: randomly sorting files in php
Message-Id: <3b-dnfsjxuAJJajMnZ2dnUVZ_qCdnZ2d@supernews.com>
[x-posted to clp.misc]
On 03/03/2013 06:59 PM, Cal Dershowitz wrote:
> On 02/28/2013 10:54 PM, David Robley wrote:
>
>> Have a look at these functions for starters:
>>
>> rand()
>> array_rand()
>> shuffle()
>>
>
> Alright, David, I'm pleased with how far I've gotten with this so far
>
> $ pwd
> /var/www
> $ ls
> CCE0-705F index.html read_dir1.php read_dir3.php read_dir5.php
> date.php music1 read_dir1.php~ read_dir3.php~ read_dir5.php~
> date.php~ music1.sh read_dir2.php read_dir4.php test.php
> hello.php music1.sh~ read_dir2.php~ read_dir4.php~ Untitled Document
> $ cat read_dir4.php
> <?php
>
> function getFilesFromDir($dir) {
>
> $files = array();
> if ($handle = opendir($dir)) {
> while (false !== ($file = readdir($handle))) {
> if ($file != "." && $file != "..") {
> if(is_dir($dir.'/'.$file)) {
> $dir2 = $dir.'/'.$file;
> $files[] = getFilesFromDir($dir2);
> }
> else {
> $files[] = $dir.'/'.$file;
> }
> }
> }
> closedir($handle);
> }
>
> return array_flat($files);
> }
>
> function array_flat($array) {
>
> foreach($array as $a) {
> if(is_array($a)) {
> $tmp = array_merge($tmp, array_flat($a));
> }
> else {
> $tmp[] = $a;
> }
> }
>
> return $tmp;
> }
>
> // Usage
> $dir = 'music1';
> $foo = getFilesFromDir($dir);
>
> print_r($foo);
> ?>
> $
>
> This is my fourth version of this script, obviously written primarily by
> someone with more experience.
>
> The output is tremendous, and the next step is to use a regex to knock
> off leading numbers and underscores. I have a simple question.
>
> Given that you have the data in an array that is instantiated like this,
> how does one use best php form to use a regex on the whole thing?
This article has me convinced that I want perl and php able to deal with
each other:
http://www.linuxjournal.com/article/9282?page=0,1
The install didn't succumb to my first try, nor the second, which was this:
cpan[1]> install PHP::Interpreter
Going to read '/home/fred/.cpan/Metadata'
Database was generated on Mon, 28 Jan 2013 12:06:54 GMT
Fetching with LWP:
http://cpan.cs.utah.edu/authors/01mailrc.txt.gz
...
so far so good, and then this thing which I've seen in the literature:
using php_config 'php-config'
Can't exec "php-config": No such file or directory at Makefile.PL line 55.
Failed to find the 'php-config' executable. Make sure you have PHP and
PHP sources installed, and that 'php-config' is in PATH. at Makefile.PL
line 55.
...
bla bla bla do not pass Go. Right now I have a default installation.
Simple question: What types of things can I get configured with
php-config? envelope data available? ftp data?
--
Cal
------------------------------
Date: Tue, 05 Mar 2013 19:43:43 +0100
From: "M. Strobel" <sorry_no_mail_here@nowhere.dee>
Subject: Re: getting perl and php to talk to each other, was Re: randomly sorting files in php
Message-Id: <apmsmvFrlnnU1@mid.uni-berlin.de>
Am 05.03.2013 10:19, schrieb Cal Dershowitz:
>
> This article has me convinced that I want perl and php able to deal with each other:
>
> http://www.linuxjournal.com/article/9282?page=0,1
>
Why not instantiate a Lua interpreter in perl? Or Ruby? And the picture on the
provided links show _who_ is doing that.
Now, seriously, this is of limited use.
/Str.
------------------------------
Date: Mon, 04 Mar 2013 17:53:06 +0000
From: Rainer Weikusat <rweikusat@mssgmbh.com>
Subject: Re: some random remarks about Moose::Manual::Concepts
Message-Id: <87boaz59x9.fsf@sapphire.mobileactivedefense.com>
Rainer Weikusat <rweikusat@mssgmbh.com> writes:
> Ben Morrow <ben@morrow.me.uk> writes:
[...]
>> Attributes in Perl should in general be wrapped in accessor methods,
>> whether those methods are considered 'public' or 'private' (or some sort
>> of C++ish 'protected'), so that subclasses can change the way they
>> work. Every time you write $self->{foo} you are requiring that every
>> subclass must use a hashref-based object containing a 'foo' key with the
>> semantics you expect.
>
> As I wrote in my original text: In general, attributes shouldn't be
> exposed at all. A class should provide methods with some kind of
> 'useful behaviour', both for subclasses and class users and how this
> behavior is actually implemented shouldn't be anybody's business. And
> I meant that.
This (what Ben Morrow wrote) is actually a sufficiently mind-boggling
idea that a more detailed comment seems appropriate. The first
observation about the 'every attribute access should go through an
accessor method' statement would be that this is impossible because
there's no way to implement 'an accessor method' if the accessor
method itself needs an accessor method to access the attribute. It
follows that the set of methods provided by a class must be
partitioned into two subsets, the subset of methods which access
class attributes directly and the subset of methods which don't do
that. Consequently, 'the class' is actually composed of 'the core
class' which is nothing but a 'dumb' data structure with some named
properties whose values users can change or retrieve with the help of
methods and a general-purpose subroutine library which could really
work with objects of any class that has (somewhat uselessly) been
'joined at the hip' with the 'core class' by residing in the same
package and one can conjecture that the set of 'general purpose
subroutines' joined to any particular class is usually envisioned as
empty, ie, that - conceptually - this amazing viewpoint doesn't really
regard objects as 'objects' providing some kind of useful behaviour
but as 'dumb data structures' manipulated by 'the code' as it sees fit,
with the additional possibility to change the 'physical
implementation' of this 'dumb datastructure' if this should be
regarded as useful for some reason I cannot currently imagine.
This is pretty consistent with a lot of Java code I've seen in the
last three weeks and I completely aggree that the Perl object system
is ill-suited for providing the equivalent of 'C structs' in Perl.
NB: Inconsistencies in this description might be a result of me still
trying to get my head around the implications of this. It is certainly
very much different from my idea of 'classes and objects'.
------------------------------
Date: Mon, 4 Mar 2013 22:52:29 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: some random remarks about Moose::Manual::Concepts
Message-Id: <d6lf0a-b5b2.ln1@anubis.morrow.me.uk>
Quoth Rainer Weikusat <rweikusat@mssgmbh.com>:
> Ben Morrow <ben@morrow.me.uk> writes:
> > Quoth Rainer Weikusat <rweikusat@mssgmbh.com>:
> >>
> >> [*] A very striking example of marketingspeak duplicity would be the
> >> way this text refers to symbol table manipulations. If code doing this
> >> is written by some class author in order to sovle a real problem, this
> >> is called 'mucking about in the symbol table' or 'symbol table
> >> hackery' but referred to as 'serious symbol table wizardry' when it is
> >> done in order to provide a Moose-feature.
> >
> > You are being so overbearingly arrogant it makes my teeth hurt.
I apologise for my rather adverarial response. I was offended by your
attitude; I still am, but responding in kind will not necessarily lead
to a fruitful discussion.
> > The perl symbol table is not a simple system. There are people in
> > the world who understand it better than you do
>
> You have absolutely no idea of my level of 'understanding' of anything
> and this 'en minature' rant has no relation whatsoever to the text I
> wrote you happened to attach it to.
You snipped the bit where I said 'even if you do understand this well
enough to do right, the advice is still good advice since most people
don't'.
> >> If the property hadn't been exposed to begin with, overloading the
> >> access method(s) in order to be able to change the implementation
> >> wouldn't be necessary.
> >
> > Attributes in Perl should in general be wrapped in accessor methods,
> > whether those methods are considered 'public' or 'private' (or some sort
> > of C++ish 'protected'), so that subclasses can change the way they
> > work. Every time you write $self->{foo} you are requiring that every
> > subclass must use a hashref-based object containing a 'foo' key with the
> > semantics you expect.
>
> As I wrote in my original text: In general, attributes shouldn't be
> exposed at all. A class should provide methods with some kind of
> 'useful behaviour', both for subclasses and class users and how this
> behavior is actually implemented shouldn't be anybody's business. And
> I meant that.
Obviously I wasn't clear. I was saying that the implementation of an
attribute should be hidden not only from subclasses and external code
but also from the implementation of the class itself. Trying to subclass
a class which hasn't done this can be rather difficult, because you have
to maintain the implementation of the attributes that the parent class
is expecting.
> > Yes, C++'s object model is junk. I think we all know that, and I'm not
> > sure what relevance it has to either Perl or Moose. (In case you were
> > under any misconception, Moose is not trying to be 'C++-in-Perl', it's
> > trying to be 'CLOS-in-Perl', approximately.)
>
> My general impression would be that it is trying to be 'Java in Perl'
> (that would be 'C++ for dummies'),
That impression is incorrect. Moose type-constraints, even when they are
used, are nothing like Java's static typing. They are much more like an
integrated form of Params::Util: a simple and correct way of performing
precondition tests on your parameters, *if you choose to*.
> > You are basically talking about the difference between what ObjC (and
> > therefore I assume Smalltalk?) calls 'formal' and 'informal protocols',
> > and saying that you prefer informal protocols.
>
> I have no idea what 'Objective-C' calls a 'formal' or an 'informal'
> protocol, consequently, I cannot possibly have written anything about
> that.
Oh, OK. I was assuming that the concepts came from Smalltalk, which you
seem to be familiar with; checking that, I find out they didn't, so
sorry about that.
As I was using those terms:
An 'informal protocol' is a list of method signatures (names, in
Perl) which an object can respond to. This list exists only in the
documentation. If an object conforms to the protocol it implements
those methods; if you want to find out if a given object conforms to
the protocol you inquire (via reflection, e.g. ->can) if the methods
are implemented.
A 'formal protocol' is also a list of methods (with associated
semantics) an object responds to, but in addition the object
declares to the runtime system (and maybe to the compiler) that it
claims to implement that protocol. It is possible to inquire, at
runtime, whether or not an arbitrary given object claims conformance
to a given formal protocol.
Informal protocols are useful when dealing with objects which are
otherwise constrained in some way: for instance, a given function might
document 'you must pass an object which responds to method M in a given
way'. If calling code passes an object which responds to M in completely
the wrong way, that's a problem with the calling code. (I believe this
is roughly your position?)
They are less useful, and more risky, when dealing with potentially
arbitrary objects; for instance, Storable defines an informal protocol
for objects which wish to be Stored in a custom format. In order to
avoid the possibility of picking up methods which were not intended to
be anything to do with Storable, the method names it uses are
deliberately obscure. If instead it checked ->DOES("Storable::Custom")
or some such, it could use more sensible method names without risk of
conflict.
Further, if UNIVERSAL defined a ->QI method, which says 'if this object
does not implement the named interface, return false; otherwise, return
a new ref to the object which will behave according to the given
interface' it would be possible to write something like
my $frozen;
if (blessed $x && my $obj = $x->QI("Storable::Custom")) {
$frozen = $obj->freeze;
}
else {
$frozen = freeze_random_scalar($x);
}
without prejudicing the ability of the object to have a different
->freeze method for some other purpose.
> >> Also, the ancestors of a class are an implemenation detail of the
> >> class (inheritance is about code reuse) and 'common behaviour of
> >> different classes' shouldn't require them to share some part of their
> >> implementations.
> >
> > Yes. This is why I would prefer classes (or, actually, objects) to
> > declare their conformance or not to something equivalent to a formal
> > protocol as the only externally-visible way of asking 'is this a duck?'.
> > Java interfaces are identical to formal protocols;
>
> objects which have an indirect relation to each other because somebody
> defined a 'meta-class' (the term 'meta' is here used with a different
> meaning than it is usually used for OOP) and the objects are both
> 'meta-instances' of the 'meta-class'. That's nothing but an
> inheritance-relationship with an additional level of indirection
> (losely spoken) born out of the necessity to be more flexible in this
> respect than 'James Gosling originally believed to be necessary' (also
> losely spoken).
This has nothing to do with inheritance (which is about code reuse,
mostly), and nothing to do with Java. ObjC has both fully-supported
multiple-inheritance and formal protocols, and they are each useful for
different things.
> Asking an object "Are you a duck?"[*], to stay with this example, is
> something which shouldn't ever be necessary, and the only sensible
> answer would be "Why do you care?"
Hmm, perhaps I should rephrase the question. ->isa asks 'are you a
duck?', and I agree one should not usually need to ask that. ->DOES asks
'can you behave like a duck?', and that is something you need to ask if
you want to know whether to treat the object as a duck or not.
> (I tend to answer the ritual 'Where
> are you from?' question in this way precisely because my
> 'implementation' shouldn't be anybody's business). The object is used
> in a certain context and either, it provides 'suitable behaviour' aka
> 'reacts in a sensible way to certain messages sent to it', than, the
> final result will hopefully be something somebody considers useful and
> otherwise, it will be a (usually fatal) runtime error.
There is a third possibility: that the object implements a method of
this name, for some other purpose, and it does something unwanted and
unexpected. As I said above, this should not be a problem when passed an
object for a specific use (though defensive programming says you should
probably check anyway), but when starting with an arbitrary object and
trying to use reflection to decide what to do with it, it can easily
happen entirely by accident.
> >> >> I'm not usually interested in fighting my tools for
> >> >> ideological reasons such as the assumption that 'strong typing' would
> >> >> be a desirable property in its own right.
> >> >
> >> > I have nothing against the way Perl works.
> >> > But I dislike this argument, maybe for 'ideological reasons'.
> >> > I take 'ideological' to be here only a derogative variant
> >> > of 'conceptual', 'abstract', 'paradigmatic'...
> >>
> >> An 'ideology' is a philosophical system sharing the trait that its
> >> proponents consider it an absolute, universal truth which has to be
> >> accepted uncritically if one doesn't want to forfeit one's 'immortal
> >> soul' with usual (monotheistic) religious systems: It is based on a
> >> set of 'core values' which are regarded as desirable because of
> >> themselves, not because of something like 'practical usefulness',
> >
> > The word you are looking for is 'dogma'.
>
> 'Dogma' is a religious term. AFAIK, it's the Roman-Catholic equivalent
> of an axiom (and the implication that theology and mathematics are
> closely related at a 'structural' level is absolutely intentional).
Yup. In English it is also routinely generalised to mean any belief
which is strongly held without or in spite of evidence.
> > 'Ideology' properly means something rather different, except that,
> > as with many philosophical terms, certain 20thC political groups
> > have twisted it to the point where it conveys very little beyond
> > 'this is BAD'.
>
> I've used it in the way it is usually used in contemporary German, eg
OK, maybe this is a translation thing. In English the term is strongly
associated with political unpleasantness, and applying it outside that
context is likely to have offensive implications.
> Marxism/ Communism would be called 'an ideology' (as would be
> [Jehova!], fascism). The way 'strong typing' is usually advocated has
> certain similarities to that, eg, the notion that people who disagree
> with 'the idea' are not simply people with a different opinion but
> 'beings of lesser value' (as in 'You are being so overbearingly
> arrogant it makes my teeth hurt.'). So far, the results haven't been
> equally murderous but considering that people have already demanded
> execution of 'global warming sceptics', this is probably rather a
> problem of not being capable of physically exterminating the
> unbelievers and not of not desiring to do so.
...then again, maybe that's exactly what you intended.
For the record: I have no desire to exterminate you, or anyone else. I
will not acquire that desire no matter what you say or believe. I would
quite like to have an intelligent discussion with you about Perl, object
systems, and so on, since you are clearly not stupid and I believe you
might have something interesting to say; that is not made very easy by
your continual use of hyperbolic rhetoric and grotesque insults.
> > The latter case is where the type system is useful. It's also useful for
> > catching errors early: if someone passes an X object when they
> > should
>
> "... just use Ada, dammit, and stop being so arrogant to assume they
> had the right to a different opinion !!!"
I have never used Ada, and have no desire to do so.
When I said 'if someone passes an X object' I did not mean the object
must be in class X (or a subclass). I meant something much more general,
along the line of 'if someone passes an object which will not do X when
method M is called...'.
> >> This implies that any object which understands a certain
> >> set of messages can be used by any code which is also aware of it.
> >
> > This constraint ('Any object which understands a certain set of
> > messages') can be easily expressed in the Moose type-constraint system,
> > should you desire to do so,
>
> But I don't desire to do so because I don't buy into the theory/
> ideology/ dogmatology/ you-name-it that 'strong typing' is the only or
> the only True[tm] way to deal with certain aspects of 'programming
> languages and environments'. That's something certain people have been
> at loggerheads about since the 1970s (probably earlier) and
> specifically, something some people from Europe considered to be
> absolutely essential from a mostly theoretical point of view while
> 'some other people' from the USA built practically useful, complex
> computer systems without it (or mostly without it). This constitutes
> empirical evidence that it isn't really essential and hence, all the
> vitriol, since humans never change their opinons on anything just
> because they are/ were demonstrably wrong.
The only vitriol here is coming from you. I explained in the post you
are replying to that the Moose type system is entirely optional, and if
you don't find it useful you don't have to use it. It also isn't a 'type
system' in the way that term is usually used; the name was poorly
chosen, IMHO. It's a system for defining automatic runtime checks on
parameters, to be used where those checks would otherwise have been
written out longhand.
> My opinion on that would be 'Could we perhaps but the matter to a rest
> and focus on more practical stuff' (Did I tell you of a really great,
> 'weakly typed' OO system I've been using productively to solve all
> kinds of 'real-world' problems for more than 15 years? No antlers
> attached :-).
If you aren't interested in learning how Moose works, why are you
reading about it? More importantly, why are you *posting* about it when
you clearly haven't properly understood it yet?
Ben
------------------------------
Date: Tue, 5 Mar 2013 00:35:06 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: some random remarks about Moose::Manual::Concepts
Message-Id: <q6rf0a-rtb2.ln1@anubis.morrow.me.uk>
Quoth Rainer Weikusat <rweikusat@mssgmbh.com>:
> Rainer Weikusat <rweikusat@mssgmbh.com> writes:
> > Ben Morrow <ben@morrow.me.uk> writes:
>
> >> Attributes in Perl should in general be wrapped in accessor methods,
> >> whether those methods are considered 'public' or 'private' (or some sort
> >> of C++ish 'protected'), so that subclasses can change the way they
> >> work. Every time you write $self->{foo} you are requiring that every
> >> subclass must use a hashref-based object containing a 'foo' key with the
> >> semantics you expect.
> >
> > As I wrote in my original text: In general, attributes shouldn't be
> > exposed at all. A class should provide methods with some kind of
> > 'useful behaviour', both for subclasses and class users and how this
> > behavior is actually implemented shouldn't be anybody's business. And
> > I meant that.
>
> This (what Ben Morrow wrote) is actually a sufficiently mind-boggling
> idea that a more detailed comment seems appropriate. The first
> observation about the 'every attribute access should go through an
> accessor method' statement would be that this is impossible because
> there's no way to implement 'an accessor method' if the accessor
> method itself needs an accessor method to access the attribute.
Obviously the accessor methods themselves need to access the attribute
directly; my point was that nothing else should.
> It
> follows that the set of methods provided by a class must be
> partitioned into two subsets, the subset of methods which access
> class attributes directly and the subset of methods which don't do
> that. Consequently, 'the class' is actually composed of 'the core
> class' which is nothing but a 'dumb' data structure with some named
> properties whose values users can change or retrieve with the help of
> methods and a general-purpose subroutine library which could really
> work with objects of any class
Any class implementing the same property interface, yes. One of the
things Moose allows you to do (or rather, makes a great deal easier) is
to move code like this into roles, which can then be composed into
otherwise unrelated classes. This is a good way of reusing code without
having to distort the inheritance hierarchy in order to do so.
> that has (somewhat uselessly) been
> 'joined at the hip' with the 'core class' by residing in the same
> package and one can conjecture that the set of 'general purpose
> subroutines' joined to any particular class is usually envisioned as
> empty,
I don't follow this last inference: classes usually have substantive
methods in addition to their accessors. In many cases the accessors will
not be part of the public interface to the class, they are just there so
that subclasses can override them if necessary.
> ie, that - conceptually - this amazing viewpoint doesn't really
> regard objects as 'objects' providing some kind of useful behaviour
> but as 'dumb data structures' manipulated by 'the code' as it sees fit,
> with the additional possibility to change the 'physical
> implementation' of this 'dumb datastructure' if this should be
> regarded as useful for some reason I cannot currently imagine.
OK, maybe an example will help. Suppose I am selling books. So I have a
whole lot of Book objects, each with 'price' and 'discount' properties,
and a method on Book
sub charge {
my ($self) = @_;
my $price = $self->{price};
my $discount = $self->{discount};
$price - POSIX::floor( ($price * $discount) / 100);
}
Now suppose some of my books are part of a standardised series, where
the pricing for each book in the series is a property of the Series the
Book belongs to rather than the Book itself. What I want to be able to
do is
package Book::InSeries;
use parent "Book";
sub price { $_[0]->series->price }
sub discount { $_[0]->series->discount }
and have the ->charge method above continue to work; as written, this is
not possible because ->charge is accessing the attributes directly.
> This is pretty consistent with a lot of Java code I've seen in the
> last three weeks and I completely aggree that the Perl object system
> is ill-suited for providing the equivalent of 'C structs' in Perl.
The Perl object system is entirely suited to this; in fact there's a
core module, Class::Struct, for doing exactly that. That's not what I'm
talking about, however.
Ben
------------------------------
Date: Tue, 05 Mar 2013 12:55:37 +0000
From: Rainer Weikusat <rweikusat@mssgmbh.com>
Subject: Re: some random remarks about Moose::Manual::Concepts
Message-Id: <87wqtmc8fq.fsf@sapphire.mobileactivedefense.com>
Ben Morrow <ben@morrow.me.uk> writes:
> Quoth Rainer Weikusat <rweikusat@mssgmbh.com>:
>> Rainer Weikusat <rweikusat@mssgmbh.com> writes:
>> > Ben Morrow <ben@morrow.me.uk> writes:
>> >> Attributes in Perl should in general be wrapped in accessor methods,
>> >> whether those methods are considered 'public' or 'private' (or some sort
>> >> of C++ish 'protected'),
[...]
>> This (what Ben Morrow wrote) is actually a sufficiently mind-boggling
>> idea that a more detailed comment seems appropriate. The first
>> observation about the 'every attribute access should go through an
>> accessor method' statement would be that this is impossible because
>> there's no way to implement 'an accessor method' if the accessor
>> method itself needs an accessor method to access the attribute.
>
> Obviously the accessor methods themselves need to access the attribute
> directly; my point was that nothing else should.
Yes. And because of this, the 'class' is actually just a structure
composed of 'some perl object' (in the sense of scalar, array, ...)
which provides access to some set of named properties via methods and
some part really shouldn't belong to the class but does for 'weird
reasons'.
[...]
> Suppose I am selling books. So I have a
> whole lot of Book objects, each with 'price' and 'discount' properties,
> and a method on Book
>
> sub charge {
> my ($self) = @_;
>
> my $price = $self->{price};
> my $discount = $self->{discount};
>
> $price - POSIX::floor( ($price * $discount) / 100);
> }
>
> Now suppose some of my books are part of a standardised series, where
> the pricing for each book in the series is a property of the Series the
> Book belongs to rather than the Book itself. What I want to be able to
> do is
>
> package Book::InSeries;
> use parent "Book";
>
> sub price { $_[0]->series->price }
> sub discount { $_[0]->series->discount }
>
> and have the ->charge method above continue to work; as written, this is
> not possible because ->charge is accessing the attributes directly.
NB: This is a contrived example but it already has some of properties
I was writing about.
The problem with this is that the 'charge' method is really not at all
related to books but a general calculation. A 'book' is just a thing
with two properties, price and discount, and 'book from a series' is
also something which has these two properties. It is merged in the
book class in order to get 'access' (in German, one would call this
'von hinten durch die Brust ins Auge', 'shot from behind through the
chest into an eye') to the charge method which is attached to book and
this seems to be the path of least resistance, given the properties of
the existing implementation.
The charge method really shouldn't be a method at all but a 'generic
function' (intentional misuse, I re-read some stuff about CLOS
yesterday) which works with any object capable of being queried for a
price and a discount and both 'individually priced book' and 'book
from a series' should be objects of different classes reacting to
'price' and 'discount' messages the charge method can work with
because interface and implementation are 'naturally separate' in
Perl-OO, anyway (especially considering the somewhat shady guy next
door who sells used handkerchiefs he acquired in some not-to-be-named
way. These also have a price and a discount and he would really like
to 're-use' the charge function, possibly without asking for
permission first ...).
I'll try to contrast this with a real example (somewhat simplified):
There's a database class whose purpose of to manage collections of
complex objects on behalf of 'some subsystem' interested in
them. These objects have properties which are really links to other
complex objects and these other objects can be updated in response to
external events. In this case, the linking object is informed that the
linked object has been updated. Depending on the object and the
property, this update may also be of interest to the database object,
eg, because the update to the linking object caused by the update of
the linked object needs to be signalled to another linking object
(possibly managed by another database, although this doesn't matter
here) or the 'object' (a subsystem aka 'classless singleton object' in
this case) which owns the database needs to perform some action
affecting some part of the outside world the database class and its
instance are not aware of, depending on where the original update came
from aka 'its type'.
This works such that the linking object notifies its 'owner' (the
database) when it actually changed because of an update to a
linked object (which is not always the case). The database, in turn,
maintains a set 'actions to be performed in case of an
update of type X'. A single external event can cause multiple updates
to linked objects which may affect any number of linking objects and
the set of updated linking objects should be passed to any 'action'
routine interested in updates of this type in a single invocation,
after all 'current' events have happened. In order to do this, the
database contains a hash mapping 'update types' to 'Interest'
objects. These define two methods, one for adding a new action to the
set of actions for this update type and one for adding a new updated
objects to the set of objects updated during this 'event cycle'. When
a database is notified of an update to a contained object, it invokes
the 'add updated object' method and when a new 'update listener'
registers an interest in a kind of update, the database invokes the
'add listener' method of the corresponding interest object, possibly
creating it first. It is not anyhow concerned with that the Interest
object actually does.
The interest object maintains an array of actions and (originally) an
array of update objects. When the 'add update object' method is
called and no 'updated objects' array exists yet, one is created and a
task which will invoke all actions registered with this interest
object at some unspecified time after control returned to the
top-level event loop is scheduled. New calls to the 'add updated'
method add new objects to the updated objects array until the
scheduled task runs which 'consumes' all of them and destroys the
'updated objects' array afterwards.
As it turned out to be, the situation that a single linking object is
updated more than one time during an 'event cycle' can also occur. In
order to deal with that, a hash keeping track of which objects are
already in the updated objects array was added to the Interest
class. This (or any other rearranagement of the way the Interest
object keeps its internal data) could be accomplished without
affecting any other part of the whole mechansism because the interface
offered by the class wasn't affected by it. Instead of changing the
Interest object implementation, another option had been to subclass it
and add the 'hash lookup' part by overloading the 'add updated' method
in a way CLOS would call 'an around method', only invoking the
original 'add updated' in case the object to be added wasn't already
added. While such a hypothectical subclass could put its instance data
into a new slot of the 'general object representation' used by the
base class (an anonymous array), it could as well just store it in any
other 'convenient' way and it doesn't have (and doesn't need) any
knowledge about how the 'base class' uses its slots of the array
reference, not even what these slots 'are' (eg, their number and their
'names').
One of the problems with 'OOP' is that simple, contrived examples are
almost always useless except for demonstrating whatever they were
supposed to demonstrate while even relatively simple 'real examples',
as the one described above (certainly a lot less than 100 LOC), are
already so hideously complicated that using them as an explanation is
next to impossible :-}.
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
Back issues are available via anonymous ftp from
ftp://cil-www.oce.orst.edu/pub/perl/old-digests.
#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V11 Issue 3892
***************************************