[32630] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 3905 Volume: 11

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Wed Mar 20 14:09:20 2013

Date: Wed, 20 Mar 2013 11:09:06 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)

Perl-Users Digest           Wed, 20 Mar 2013     Volume: 11 Number: 3905

Today's topics:
    Re: 'Needless flexibilities' and structured records [ve <ben@morrow.me.uk>
    Re: 'Needless flexibilities' and structured records [ve <rweikusat@mssgmbh.com>
    Re: 'Needless flexibilities' and structured records [ve <ben@morrow.me.uk>
    Re: 'Needless flexibilities' and structured records [ve <ben@morrow.me.uk>
        CPAN Versioning <finanztest@freenet.de>
    Re: CPAN Versioning <ben@morrow.me.uk>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: Tue, 19 Mar 2013 01:43:02 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: 'Needless flexibilities' and structured records [very long]
Message-Id: <6esk1a-ho31.ln1@anubis.morrow.me.uk>


Quoth Rainer Weikusat <rweikusat@mssgmbh.com>:
> Ben Morrow <ben@morrow.me.uk> writes:
> 
> [...]
> 
> >> ---------------
> >> package slots;
> >> 
> >> use feature 'state';
> >> use constant;
> >> 
> >> sub import
> >> {
> >>     state %counters;
> >>     my ($ctr, $fields);
> >> 
> >>     if (ref($_[1])) {
> >> 	$fields = $_[1];
> >> 	$ctr = 0;
> >>     } else {
> >> 	$ctr = $counters{$_[1]};
> >
> > You can look up the inheritance here instead of having the user specify
> > it (DRY and all that...). As long as they
> 
> Re: DRY
> 
> That's a cute acronym for 'Design pattern aficionados Reinventing
> elementary database theorY' (in short: Databases should not contain
> redundant copies of the same data to avoid so-called 'update
> anomalies', the database becoming inconsistent because not all
> redudant copies of 'some data' are changed during an update. People
> usually ignore that in favor of 'nobdoy will ever update X without
> going to gatekeeper code Z which always keeps all copies in sync' and
> looking dedicatedly in another direction whenever somebody mentions
> that 'updates withoug going throug Z' are possible. This could almost
> be called 'a basic design principle of modern Linux distributions'
> :->).

Um, what?

> >     use parent "Parent";
> >     use slots qw/one two three/;
> >
> > in that order, @{ caller . "::ISA" } will contain the direct parents at
> > this point. You can also croak if they're trying to use MI.
> 
> I thought about that and decided against it: This would require @ISA
> to be populated by the time the import method is executed and the code
> would either need to operate in 'pushy nanny mode' ("I've told you you
> must not inherit methods from more than one class and you must do as I say
> because I say so!") or make a guess at which of the possibly many
> direct and indirect(!) 'superclasses' is supposed to be the anchoring
> point for the new slot name series. But in reality, @ISA is about
> method lookups and not about 'allocating array slots in a
> non-conflicting way to members of some "inheritance tree"'.
> 
> One can assume that packages sharing an array reference for instance
> data will usually also share method via @ISA but this need not be
> true.

I suppose; certainly a facility to inherit slots independently of @ISA
might be useful. Data and method inheritance staying in sync must be the
overwhelmingly common case, though, so optimising the 'use' interface
for that would seem sensible.

> Also just because some package is listed in @ISA doesn't
> necessarily mean that it should also participiate in the 'data
> inheritance hierarchy'. These are orthogonal issues and one of the
> serious drawbacks of many existing 'OO support modules' is that the
> authors usually fell prey to their own "Jack of all trades" desires
> and 'hard-coded' technically independent policy choices they usually
> happen to make in their code. Eg, one cannot comfortably use parent.pm
> except if one always keeps each package in a file of its own, to name
> a simple example.

    use parent -norequire => "Foo";

though I see little advantage to that over

    BEGIN { push @ISA, "Foo" }

(or omit the BEGIN if it doesn't make a difference, which it usually
doesn't).

> >> 	$fields = $_[2];
> >>     }
> >>      
> >>     @_ = ($_[0], {map { $_, $ctr++; } @$fields});
> >
> > Strictly this should be "constant" rather than $_[0] (which will be
> > "slots"), since this is supposed to be emulating constant->import. In
> > fact constant.pm doesn't care, but in principle it might care at some
> > point in the future.
> 
> It would be 'constant' if constant::import had actually been
> invoked directly. But since this isn't the case and no 'requirements
> specification' of any kind exists (as far as I'm aware of that)
> anything would do insofar it pushes the first 'actual argument' to
> $_[1].

The only documented interface to constant.pm is via 'use'. This will
call constant::import with $_[0] = "constant", so that is an implicit
part of the 'requirements specification' for using constant.pm. It's
only by chance that constant::import happens to ignore its first
argument: it would be entirely possible, and might even be sensible, for
constant to share its import routine with (say) subs and vars, and use
the first argument to determine what it was supposed to be exporting.

(Of course, it would be much better if constant.pm supplied a
constant::create routine which took the package the constant should be
created in as an argument. Then you wouldn't need goto-&. In retrospect,
'use' should probably have supplied the importing package name as an
argument, rather than implicitly through caller().)

> Using whatever was passed in $_[0] to this import routine is as
> good an anything as anything else and might also be useful 'in
> future'.

Useful how? What could constant possibly do with that information that
might be useful, given that it's completely unexpected?

> >>     $counters{caller()} = $ctr;
> >> 
> >>     goto &constant::import;
> >
> > It's probably easier to just create the constants manually, rather than
> > bothering with goto-&:
> >
> >     for (@$fields) {
> >         my $n = $ctr++;
> >         no strict "refs";
> >         *{ caller . "::$_" } = sub () { $n };
> >     }
> >
> > If you were feeling excited you could use the scalar-refs-in-the-stash
> > trick constant.pm uses to avoid a full GV+CV.
> 
> Ehh ... I'm using the 'scalar-refs-in-the-stash' trick and - for that
> matter - any useful other 'trick' constant.pm might employ now or in
> future. That's why I'm just telling constant.pm which constants I'd
> like to have created[*].
> 
> This is also a design question: Since a subroutine providing the
> feature I want to build on already exists and the implementation is
> suitable for the task at hand, the code should rather invoke the
> subroutine than be decorated by copy of some of its code (this is also
> a 'DRY/ redundant copies of identical data' issue).

That's a fair point. If constant supplied a standalone constant-creation
routine that could be called normally, I would definitely advocate using
it. In this case, though, I consider goto-& ugly enough to be worth
avoiding where possible.

> >> use slots ('Person', ['NATIONALITY']);
> >> 
> >> ('Person' being the name of the superclass package) to request an
> >> additional field which will have the next 'free' slot number.
> >> 
> >> NB: This is an idea I had yesterday and since the implementation was
> >> so exceedingly simple, I thought sharing it might be a good idea. I
> >> expect that there situations this simple code doesn't handle but it is
> >> 'good enough' to be useful.
> >
> > It's not a bad idea; it's basically the same as Class::Accessor::Faster
> > or MooseX::ArrayRef.
> 
> I assume the authors of the two named modules would calls this 'a
> backhanded compliment' (and rightly so :->) and so would I (also
> rightly so :->). This is a slight generalization of an anonymous array
> sharing scheme I've been using since 199x and it really doesn't (and
> shouldn't) do anything except solve this particular problem.

I was trying to be polite. You were presenting it as a revelation the
like of which Perl had never seen before; in fact, it's a rather obvious
idea, with very few advantages over standard hashref-based objects, and
some important disadvantages. In some specific situations, in particular
where saving memory is important, it might be useful, but for general
use it doesn't seem to me worth expending effort trying to work around
the problems with arrayref objects unless you want to do a complete job
and solve all the problems.

> > As you note, it only works for single inheritance,
> > and doesn't work with MI or roles-which-provide-attributes (however they
> > may be implemented); it also fails (badly) if you attempt to modify the
> > inheritance or attributes of a class at runtime.
> 
> It can't 'fail badly at run-time' because the code never runs 'at
> run-time'.

The created classes run code at runtime, and that code will fail if the
properties of the class have been changed since it was compiled.

> This 'anonymous array sharing scheme' might not be useful
> to solve 'certain problems' or might only be a component which could
> be employed for solving them. But that's a different conversation (I
> already wrote about the
> washer-dryer-lawnmower-bicycle-tophat-eggwarmer-hovercraft-theodolite
> ... sometimes, a hammer is really the right tool).

Sometimes, yes. Most of those times, I'd just use an arrayref directly,
and probably not even bother with the constants. IMHO once an object
expands beyond a tuple of two or three values, or a class acquires
inheritance, it's worth using a system which is always going to work.

> A more general remark: [snip irrelevant verbosity with delusions of
> academia]
>
> So far (evil anecdotical argument), I haven't been stopped by a brick
> wall when using that for the problems I head to deal
> with. Consequently, I'm not convinced that it needs to be replaced
> with a system based on different policy choices, especially
> considering that 'simple system for solving relatively simple
> problems' are useful because many problems are relatively simple

Noone is 'replacing' Perl 5 OO, at least not in Perl 5. Some people have
found, as a practical matter rather than an academic consideration, that
the obvious way of using Perl 5 OO is not sufficient for their needs;
they have used the flexibility you seem to be so proud of to build a
system that is. This system is optional, and will remain so as long as
Perl 5 exists. If you don't wish to use it, you needn't have anything to
do with it; so I don't see why you keep having to be so snotty about it.

> (Corollary: Problems which only manifest themselves dreadfully in 'really
> large systems' could be a sign that createing 'really large systems'
> is 'a really bad idea').

That may be true, but sometimes it's necessary, given that there are
Really Complicated Problems in the real world that need to be solved.
Some of them could perhaps be solved better by a set of loosely-coupled
smaller systems; I am in general in favour of this approach myself, but
it isn't always possible, for reasons both technical and non-technical.

On top of that, Moose isn't just about solving problems-in-the-large:
once you get used to it, it's a *lot* more pleasant to work with than
raw Perl OO. I think so, anyway, and so do a lot of other people; if you
don't, that's fine, don't use it, but there's no need to be insulting
about it. Different people are entitled to different opinions.

> I'm also a firm desbeliever in 'the run-time environment has to defend
> itself agains one million evil typing monkeys'. That's a social
> problem and the solutions are 'education' and 'natural selection'.

I don't trust you or me or anyone to get everything right all the time.
Defensive programming is all about assuming you might not, and finding
ways to limit the damage when you don't.

(Also, 'natural selection' is not the solution to any social problem. I
assume you know who the Social Darwinists were?)

Ben



------------------------------

Date: Tue, 19 Mar 2013 13:59:43 +0000
From: Rainer Weikusat <rweikusat@mssgmbh.com>
Subject: Re: 'Needless flexibilities' and structured records [very long]
Message-Id: <87vc8nfxak.fsf@sapphire.mobileactivedefense.com>

Ben Morrow <ben@morrow.me.uk> writes:
> Quoth Rainer Weikusat <rweikusat@mssgmbh.com>:
>> Ben Morrow <ben@morrow.me.uk> writes:

[...]

>> > You can look up the inheritance here instead of having the user specify
>> > it (DRY and all that...). As long as they
>> 
>> Re: DRY
>> 
>> That's a cute acronym for 'Design pattern aficionados Reinventing
>> elementary database theorY' (in short: Databases should not contain
>> redundant copies of the same data to avoid so-called 'update
>> anomalies', the database becoming inconsistent because not all
>> redudant copies of 'some data' are changed during an update. People
>> usually ignore that in favor of 'nobdoy will ever update X without
>> going to gatekeeper code Z which always keeps all copies in sync' and
>> looking dedicatedly in another direction whenever somebody mentions
>> that 'updates withoug going throug Z' are possible. This could almost
>> be called 'a basic design principle of modern Linux distributions'
>> :->).
>
> Um, what?

You can get an explanation in more detail than I care to read at the
moment here:

http://en.wikipedia.org/wiki/Database_normalization

If you strip out the technicalities relating to relational database
management systems, you arrive at 'the DRY principle'.

[...]

>
>> >     use parent "Parent";
>> >     use slots qw/one two three/;
>> >
>> > in that order, @{ caller . "::ISA" } will contain the direct parents at
>> > this point. You can also croak if they're trying to use MI.
>> 
>> I thought about that and decided against it: This would require @ISA
>> to be populated by the time the import method is executed and the code
>> would either need to operate in 'pushy nanny mode' ("I've told you you
>> must not inherit methods from more than one class and you must do as I say
>> because I say so!") or make a guess at which of the possibly many
>> direct and indirect(!) 'superclasses' is supposed to be the anchoring
>> point for the new slot name series. But in reality, @ISA is about
>> method lookups and not about 'allocating array slots in a
>> non-conflicting way to members of some "inheritance tree"'.
>> 
>> One can assume that packages sharing an array reference for instance
>> data will usually also share method via @ISA but this need not be
>> true.
>
> I suppose; certainly a facility to inherit slots independently of @ISA
> might be useful. Data and method inheritance staying in sync must be the
> overwhelmingly common case, though, so optimising the 'use' interface
> for that would seem sensible.

The issue is really that the @ISA array has a defined meaning: It is
used to facilitate subroutine sharing outside of the normal export/
import mechanism. This can be envisioned as being "a feeble/ strange
way to declare 'class ancestor/ descendant' relationships" and it is
usually even referred to as such but this is just 'a notational
convenience' and it really isn't something like this.

Eg, the most common case of 'multiple inheritance' I'm presently
dealing with is a package named 'Thing' and all it provides is an
overloaded ""-operation which prints the package some reference is
blessed into, followed by the refaddr, followed by a 'tag' of some
kind in []. A package which wants to inherit this "" needs to provide
a tag method returning a tag and the Thing package maintains a cache
of 'object tags' in a package-global hash. This is supposed to make
diagnostic messages more intelligible and the provided functionality
is independent of any properties of packages 'inheriting' from Thing.

>> Also just because some package is listed in @ISA doesn't
>> necessarily mean that it should also participiate in the 'data
>> inheritance hierarchy'. These are orthogonal issues and one of the
>> serious drawbacks of many existing 'OO support modules' is that the
>> authors usually fell prey to their own "Jack of all trades" desires
>> and 'hard-coded' technically independent policy choices they usually
>> happen to make in their code.

'Optimising for the common case' is really the same as 'hardcoding
technically unrelated policy choices' because someone considered them
"overwhelmingly important" or even "the only Right choice" or so but
in practice, this still just means "How I happen would have done
that" and how justified the generalization actually is is usally
unknown.

Some people consider 'make the right policy ch

[...]

>> >>     @_ = ($_[0], {map { $_, $ctr++; } @$fields});
>> >
>> > Strictly this should be "constant" rather than $_[0] (which will be
>> > "slots"), since this is supposed to be emulating constant->import. In
>> > fact constant.pm doesn't care, but in principle it might care at some
>> > point in the future.
>> 
>> It would be 'constant' if constant::import had actually been
>> invoked directly. But since this isn't the case and no 'requirements
>> specification' of any kind exists (as far as I'm aware of that)
>> anything would do insofar it pushes the first 'actual argument' to
>> $_[1].
>
> The only documented interface to constant.pm is via 'use'. This will
> call constant::import with $_[0] = "constant", so that is an implicit
> part of the 'requirements specification' for using constant.pm.

'Implicit [part of] the specification' is a contradiction in
adiecto. When invoking constant::import via use, the first argument
happens to be 'constant'. Since nothing is documented about invoking
constant::import in any other situation, no information regarding what
the first argument is supposed to be then is available. One can argue
that the conservative choice would be to pass 'constant' as first
argument,


> It's only by chance that constant::import happens to ignore its first
> argument:

but given the code is written in the way it is, this isn't really
needed.

NB: The obvious counterargument would be that using goto & to hide
the caller but then pass information about it to the called routine
nevertheless is 'internally add odds with itself' but I just felt a
bit 'full disclosure anarchistic' when writing the code.

[...]

>>> It's not a bad idea; it's basically the same as Class::Accessor::Faster
>>> or MooseX::ArrayRef.
>> 
>> I assume the authors of the two named modules would calls this 'a
>> backhanded compliment' (and rightly so :->) and so would I (also
>> rightly so :->). This is a slight generalization of an anonymous array
>> sharing scheme I've been using since 199x and it really doesn't (and
>> shouldn't) do anything except solve this particular problem.
>
> I was trying to be polite.

But you were actually impolite in all directions: Both modules you
named are supposed to provide 'something completely different' and in
the case of Class:: it isn't even clear (to me, at least) whether
this involves using anonymous arrays as object representation at all.
I was trying to be polite by formulating this in this way instead of
just pointing out that I strongly disagree with 'certain
implementation choices' implicit in Class:: and Moose::antyhing and
really don't appreciate something sensible I wrote being dragged into
these pits. 

> You were presenting it as a revelation the like of which Perl had
> never seen before;

I presented a scheme for manageing array slots in shared, anonymous
arrays and while this scheme is very simple, it is useful and it hasn't
(to the best of my knowledge) been published in some 'canned',
ready-to-use form so far (except maybe as 'minor internal part' of
another Wolpertinger-module). Also, minus a few hints in the Perl
documentation, I'm not aware of any actual discussion of the
advantages and disadvantages of using different kinds of Perl objects
as object representation.

> in fact, it's a rather obvious idea, with very few advantages over
> standard hashref-based objects, and some important disadvantages.
> In some specific situations, in particular where saving memory is
> important, it might be useful, but for general use it doesn't seem
> to me worth expending effort trying to work around the problems with
> arrayref objects unless you want to do a complete job and solve all
> the problems.

Please feel free to argue against the points in favour of using
anonymous arrays for object representation and against using anonymous
hashes I made. I consider them sound but argueing against them should
certainly be possible. The 'summary judgement plus hand-waiving' above
isn't useful for anyone trying to make an informed descision
himself. We already had 'one million flies' aka 'the standard way' aka
'but everyone [I consider relevant] does it that way' -- that's a
logical fallacy also known as 'ad populum' fallacy,

http://www.skepdic.com/adpopulum.html

and even your somewhat repetitive insistence of generalizing each
specific problem situation until the specific solution to that no
longer suits the expanded problem is sort-of a 'well-known'
'discussion technology' of less-than-excellent reputation,

http://www.whale.to/m/disin.html

in particular, 12/14 (and maybe 8 for the 'qualitative summary
judgement' trick).

[...]

>> This 'anonymous array sharing scheme' might not be useful
>> to solve 'certain problems' or might only be a component which could
>> be employed for solving them. But that's a different conversation (I
>> already wrote about the
>> washer-dryer-lawnmower-bicycle-tophat-eggwarmer-hovercraft-theodolite
>> ... sometimes, a hammer is really the right tool).
>
> Sometimes, yes. Most of those times, I'd just use an arrayref directly,
> and probably not even bother with the constants.

Using magic, numerical values in code is something which should - in
my opinion - almost always be avoided, especially so if the actual
numerical values have no relation to their use (eg, for an anonymous
array used as object representation, it usuallg doesn't matter which
'instance property' is associated with which slot number).


------------------------------

Date: Tue, 19 Mar 2013 22:36:27 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: 'Needless flexibilities' and structured records [very long]
Message-Id: <bs5n1a-hon1.ln1@anubis.morrow.me.uk>


Quoth Rainer Weikusat <rweikusat@mssgmbh.com>:
> Ben Morrow <ben@morrow.me.uk> writes:
> > Quoth Rainer Weikusat <rweikusat@mssgmbh.com>:
> >> Ben Morrow <ben@morrow.me.uk> writes:
> 
> >> > You can look up the inheritance here instead of having the user specify
> >> > it (DRY and all that...). As long as they
> >> 
> >> Re: DRY
> >> 
> >> That's a cute acronym for 'Design pattern aficionados Reinventing
> >> elementary database theorY' (in short: Databases should not contain
> >> redundant copies of the same data to avoid so-called 'update
> >> anomalies', the database becoming inconsistent because not all
> >> redudant copies of 'some data' are changed during an update. People
> >> usually ignore that in favor of 'nobdoy will ever update X without
> >> going to gatekeeper code Z which always keeps all copies in sync' and
> >> looking dedicatedly in another direction whenever somebody mentions
> >> that 'updates withoug going throug Z' are possible. This could almost
> >> be called 'a basic design principle of modern Linux distributions'
> >> :->).
> >
> > Um, what?
> 
> You can get an explanation in more detail than I care to read at the
> moment here:
> 
> http://en.wikipedia.org/wiki/Database_normalization

Yes, I know what database normalisation is. I don't see what relevance
it has here, nor what relevance the design of Linux distros has.

> If you strip out the technicalities relating to relational database
> management systems, you arrive at 'the DRY principle'.

So? I assume you're trying to make a point, rather than just talking to
hear yourself speak, but I can't see what it might be.

> >> >     use parent "Parent";
> >> >     use slots qw/one two three/;
> >> >
> >> > in that order, @{ caller . "::ISA" } will contain the direct parents at
> >> > this point. You can also croak if they're trying to use MI.
> >> 
> >> I thought about that and decided against it: This would require @ISA
> >> to be populated by the time the import method is executed and the code
> >> would either need to operate in 'pushy nanny mode' ("I've told you you
> >> must not inherit methods from more than one class and you must do as I say
> >> because I say so!") or make a guess at which of the possibly many
> >> direct and indirect(!) 'superclasses' is supposed to be the anchoring
> >> point for the new slot name series. But in reality, @ISA is about
> >> method lookups and not about 'allocating array slots in a
> >> non-conflicting way to members of some "inheritance tree"'.
> >> 
> >> One can assume that packages sharing an array reference for instance
> >> data will usually also share method via @ISA but this need not be
> >> true.
> >
> > I suppose; certainly a facility to inherit slots independently of @ISA
> > might be useful. Data and method inheritance staying in sync must be the
> > overwhelmingly common case, though, so optimising the 'use' interface
> > for that would seem sensible.
> 
> The issue is really that the @ISA array has a defined meaning: It is
> used to facilitate subroutine sharing outside of the normal export/
> import mechanism.

No, it's used to implement method dispatch. This is quite different from
sub sharing; for one thing, it uses a different call syntax.

> This can be envisioned as being "a feeble/ strange
> way to declare 'class ancestor/ descendant' relationships" and it is
> usually even referred to as such but this is just 'a notational
> convenience' and it really isn't something like this.
> 
> Eg, the most common case of 'multiple inheritance' I'm presently
> dealing with is a package named 'Thing' and all it provides is an
> overloaded ""-operation which prints the package some reference is
> blessed into, followed by the refaddr, followed by a 'tag' of some
> kind in []. A package which wants to inherit this "" needs to provide
> a tag method returning a tag and the Thing package maintains a cache
> of 'object tags' in a package-global hash. This is supposed to make
> diagnostic messages more intelligible and the provided functionality
> is independent of any properties of packages 'inheriting' from Thing.

This technique is called 'mixins' (at least, it is in the Perl world),
and it used to be the standard way of abstracting out functionality:
see, for example, LWP or DBIx::Class, both of which use it extensively.
It has a number of important disadvantages, however:

    - It distorts the inheritance hierarchy for an implementation
      convenience. Inheritance is supposed to be an 'is-a' relationship;
      using it just as a way to bring in methods is not helpful.

    - It can be difficult to find out where a given object's
      implementation of a given method comes from. ->can gives no
      information about this, so the whole inheritance tree has to be
      searched, by hand, in the right order.

    - There is no means of detecting when one mixin has accidentally
      overriden a method which was supposed to be provided by another.
      This is a particular problem in Perl, where any utility sub
      created in a given package will end up exported as a method,
      unless steps are taken to prevent that.

The idea of roles is to provide an alternative which avoids these
problems; in particular, if two roles imported into the same class
provide conflicting methods, the system throws an error unless the class
overrides them both itself.

> >> Also just because some package is listed in @ISA doesn't
> >> necessarily mean that it should also participiate in the 'data
> >> inheritance hierarchy'. These are orthogonal issues and one of the
> >> serious drawbacks of many existing 'OO support modules' is that the
> >> authors usually fell prey to their own "Jack of all trades" desires
> >> and 'hard-coded' technically independent policy choices they usually
> >> happen to make in their code.
> 
> 'Optimising for the common case' is really the same as 'hardcoding
> technically unrelated policy choices' because someone considered them
> "overwhelmingly important" or even "the only Right choice" or so but
> in practice, this still just means "How I happen would have done
> that" and how justified the generalization actually is is usally
> unknown.

Optimising for the common case doesn't mean making functionality
unavailable, it just means making the 'easy' interface work the way you
usually want it to. An alternative interface, like, say

    use slots;
    BEGIN { slots::inherit "Parent", [qw/one two three/] }

is probably enough for the rare occasions where data inheritance
shouldn't follow code inheritance.

> Some people consider 'make the right policy ch

EUNFINISHEDSENTENCE

> >>> It's not a bad idea; it's basically the same as Class::Accessor::Faster
> >>> or MooseX::ArrayRef.
> >> 
> >> I assume the authors of the two named modules would calls this 'a
> >> backhanded compliment' (and rightly so :->) and so would I (also
> >> rightly so :->). This is a slight generalization of an anonymous array
> >> sharing scheme I've been using since 199x and it really doesn't (and
> >> shouldn't) do anything except solve this particular problem.
> >
> > I was trying to be polite.
> 
> But you were actually impolite in all directions: Both modules you
> named are supposed to provide 'something completely different' and in
> the case of Class:: it isn't even clear (to me, at least) whether
> this involves using anonymous arrays as object representation at all.

It does. Class::Accessor::Faster provides almost exactly the same as
slots: it gives you a constructor, and accessors, for an arrayref-based
object, and nothing else.

> I was trying to be polite by formulating this in this way instead of
> just pointing out that I strongly disagree with 'certain
> implementation choices' implicit in Class:: and Moose::antyhing and
> really don't appreciate something sensible I wrote being dragged into
> these pits. 

So you have said, though you have yet to explain your disagreement
beyond 'I didn't write it' and 'I don't like it, *WAH*'. I don't
consider what you wrote to be particularly sensible, especially given
that there is a better implementation already on the CPAN.

> > You were presenting it as a revelation the like of which Perl had
> > never seen before;
> 
> I presented a scheme for manageing array slots in shared, anonymous
> arrays and while this scheme is very simple, it is useful and it hasn't
> (to the best of my knowledge) been published in some 'canned',
> ready-to-use form so far (except maybe as 'minor internal part' of
> another Wolpertinger-module).

Had you cared to look, you would have found that CAF is pretty-much
exactly the same thing.

> Also, minus a few hints in the Perl
> documentation, I'm not aware of any actual discussion of the
> advantages and disadvantages of using different kinds of Perl objects
> as object representation.

This is largely because it makes very little difference in practice what
representation you use, so most people have more interesting things to
talk about. That said, it might be interesting to see some benchmark
numbers for array-based vs hash-based objects, for some realistic
situations; memory benchmarks are probably more interseting that speed.

> > in fact, it's a rather obvious idea, with very few advantages over
> > standard hashref-based objects, and some important disadvantages.
> > In some specific situations, in particular where saving memory is
> > important, it might be useful, but for general use it doesn't seem
> > to me worth expending effort trying to work around the problems with
> > arrayref objects unless you want to do a complete job and solve all
> > the problems.
> 
> Please feel free to argue against the points in favour of using
> anonymous arrays for object representation and against using anonymous
> hashes I made. I consider them sound but argueing against them should
> certainly be possible.

I have given some of the disadvantages already:
    
    - Inheriting attributes from more than one parent, by any means, is
      more difficult to get right;

    - Changing the attributes of a class at runtime (including changing
      the inheritance) will cause existing compiled methods to refer to
      the wrong attributes; this sort of static behaviour is very
      un-Perl;

and I don't yet see any reason to think the extra complexity involved is
worth it.

> The 'summary judgement plus hand-waiving' above
> isn't useful for anyone trying to make an informed descision
> himself. We already had 'one million flies' aka 'the standard way' aka
> 'but everyone [I consider relevant] does it that way' -- that's a
> logical fallacy also known as 'ad populum' fallacy,

No, it isn't. What I actually said was 'you can do it like that if you
like, but stop complaining about other people doing it differently'.

> >> This 'anonymous array sharing scheme' might not be useful
> >> to solve 'certain problems' or might only be a component which could
> >> be employed for solving them. But that's a different conversation (I
> >> already wrote about the
> >> washer-dryer-lawnmower-bicycle-tophat-eggwarmer-hovercraft-theodolite
> >> ... sometimes, a hammer is really the right tool).
> >
> > Sometimes, yes. Most of those times, I'd just use an arrayref directly,
> > and probably not even bother with the constants.
> 
> Using magic, numerical values in code is something which should - in
> my opinion - almost always be avoided, especially so if the actual
> numerical values have no relation to their use (eg, for an anonymous
> array used as object representation, it usuallg doesn't matter which
> 'instance property' is associated with which slot number).

You snipped the bit where I said I would only apply this in the case of
a tuple of two or three attributes. Treating a two-element array as a
pair is common in Perl, and not particularly confusing.

Ben



------------------------------

Date: Tue, 19 Mar 2013 23:48:40 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: 'Needless flexibilities' and structured records [very long]
Message-Id: <o3an1a-7go1.ln1@anubis.morrow.me.uk>


Quoth Ben Morrow <ben@morrow.me.uk>:
> 
> An alternative interface, like, say
> 
>     use slots;
>     BEGIN { slots::inherit "Parent", [qw/one two three/] }
> 
> is probably enough for the rare occasions where data inheritance
> shouldn't follow code inheritance.

Meh. Obviously I meant something more like

    use slots;
    BEGIN { 
        slots::setup_slots __PACKAGE__, "Parent",   
            [qw/one two three/];
    }

Passing the package to modify implicitly via caller limits flexibility
just as it does with constant.

Ben



------------------------------

Date: Wed, 20 Mar 2013 15:17:55 +0100
From: Bummibaer <finanztest@freenet.de>
Subject: CPAN Versioning
Message-Id: <5149c514@news.fhg.de>


Hi,

How does the versioning on CPAN work? I have a script for updating every night,
but it's annoying, that some modules install every day.
Example:
Math::BigRat ( https://rt.cpan.org/Public/Bug/Display.html?id=82288)

The file is Math-BigRat-0.2602.tar.gz, the installed Version is:
	 0.2602,
  but CPAN/CPANPLUS and the CPANPLUS::Backend shows as latest version
	0.2603.
Where does it come from?
The same with  Term::Cap.





------------------------------

Date: Wed, 20 Mar 2013 15:43:34 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: CPAN Versioning
Message-Id: <622p1a-jfc2.ln1@anubis.morrow.me.uk>


Quoth Bummibaer <finanztest@freenet.de>:
> 
> How does the versioning on CPAN work? I have a script for updating
> every night, but it's annoying, that some modules install every day.

I'm not at all sure that's a good idea, at least not on a production
machine.

> Example:
> Math::BigRat ( https://rt.cpan.org/Public/Bug/Display.html?id=82288)
> 
> The file is Math-BigRat-0.2602.tar.gz, the installed Version is:
> 	 0.2602,
>   but CPAN/CPANPLUS and the CPANPLUS::Backend shows as latest version
> 	0.2603.
> Where does it come from?

Math::BigRat 0.2603 is part of perl 5.16.3. Math::BigRat is a dual-life
module, that is, it is also supplied with the perl core. In the perl
core distribution, Math-BigRat is under dist/, which means this is a
'core-leads' module: that is, updates will go into the core version
before they are released separately on CPAN. It's not uncommon for
modules like that to be a minor version ahead in the core; usually it's
because someone's had to patch it to compensate for a core change, and
the maintainer hasn't rolled a new CPAN release yet.

cpanm (App::cpanminus) gets this right.

> The same with  Term::Cap.

I'm not sure what's happened with Term::Cap: it's in cpan/ in the core,
so it should be CPAN-leads, but the core is at version 1.13 while the
latest CPAN version is 1.12. Probably whoever patched it to 1.13 didn't
realise they should have sent the changes to the maintainer first to
push to CPAN; you could try reporting a core bug.

Ben



------------------------------

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 3905
***************************************


home help back first fref pref prev next nref lref last post