some random remarks about Moose::Manual::Concepts

Discussion in 'Perl Misc' started by Rainer Weikusat, Mar 2, 2013.

  1. The complete text is available here:

    http://search.cpan.org/~doy/Moose-2.0604/lib/Moose/Manual/Concepts.pod

    ,----
    | Attributes are not methods, but defining them causes various accessor
    | methods to be created. At a minimum, a normal attribute will have a
    | reader accessor method. Many attributes have other methods, such as a
    | writer method, a clearer method, or a predicate method ("has it been
    | set?").
    `----

    This idea seems to have been 'borrowed' from 'Javabeans'. But
    considering that the whole point of classes is to hide their
    implementation details from class users, automatically generating
    a set of 'access methods' which is isomorph to the set of implementation
    details seems wrong to me. Some 'attributes' (or 'properties') may
    indeed need to be publically accessible but the majority of them
    shouldn't: There's no conceptual difference between a 'structure'
    which has only public members and a class which exposes all of its
    attributes via 'getter' and 'setter' &c methods, the latter is just a
    way to accomplish the same as the former with more overhead.

    ,----
    | A method is very straightforward. Any subroutine you define in your
    | class is a method. Methods correspond to verbs, and are what your
    | objects can do. For example, a User can login.
    `----

    The 'static OO language' background is again shining through here
    clearly. The people who are usually credited with inventing 'modern
    OO' in form of Smalltalk didn't think of methods as 'subroutines tied
    to an instance of a datastructure' but as 'messages' which can be sent
    to otherwise intransparent 'objects' which may or may not react to
    such a message in whatever way they chose to. The same is true for
    'Perl OO' -- any method name can be used on any object instance and it
    is up to the class to react to this message in whatever way it sees
    fit, including that what it sees fit may change over time. Perl is
    clearly not 'modern' here insofar modern is regarded as equivalent to
    'try to get as much Smalltalk out of a C-compiler which can
    conceivably be gotten out of it without adding intolerable overhead
    for 1980s hardware' aka 'C++' and all its conceptual descendants.

    ,----
    | A role is something that a class does. We also say that classes
    | consume roles. For example, a Machine class might do the Breakable
    | role, and so could a Bone class. A role is used to define some concept
    | that cuts across multiple unrelated classes, like "breakability", or
    | "has a color".
    |
    | [...]
    |
    |
    | Role are somewhat like mixins or interfaces in other OO languages.
    `----

    An 'interface' is the Java-way to work around the problem that
    'methods' are not 'messages' and hence, without additional declaration
    hackery, instances of unrelated classes can't be used by the same code
    even despite they may define other methods compatible with what this
    code expects. Since 'Perl OO' is message-based and not 'compile-time
    relationship' based, this kludge simply isn't needed: Any Perl code
    can send any kind of message to any Perl object.

    The reason why I'm refering to this as 'a kludge' is that the sole
    purpose of an interface declaration is to inform the compiler that two
    things which aren't different in a certain aspect, eg, when two
    unrelated classes implement two identically-named methods with
    identical return types and signatures (prototypes?) are really not
    different in this aspect despite the compiler is not capable of/
    suposed to(?) detect this on its own.

    ,----
    | Method Modifiers
    |
    | Could only be done through serious symbol table wizardry, and you
    | probably never saw this before (at least in Perl 5).
    `----

    I indeed didn't see this anywhere since I read through the CLOS
    combination rules for generic methods for the last time, something I
    always considered a prime example of the desire to build the universal
    abstraction gone wild without any concern for good design and
    practical usefulness ('good design' is supposed to refer to
    "perfection is not when there's nothing more to add but when there's
    nothing more to be removed").

    Strangely, I also didn't miss it.

    ,----
    | Type
    |
    | Hand-written parameter checking in your new() method and accessors.
    |
    | With Moose, you define types declaratively, and then use them by name
    | with your attributes.
    `----

    With Perl, I write code which works when its arguments satisfy certain
    constraints and leave it to the caller to meet these
    constraints. 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.
    Rainer Weikusat, Mar 2, 2013
    #1
    1. Advertising

  2. Rainer Weikusat

    Marc Girod Guest

    Difficult to address 'random remarks'...
    Especially I cannot do it in the context of Moose::Manual::Concepts
    which could build up a consistent background: I never used Moose.

    On Mar 2, 5:07 pm, Rainer Weikusat <> wrote:

    > the latter is just a
    > way to accomplish the same as the former with more overhead.


    Right, apart for making overriding possible.
    This is once again a case of pay now, find why (maybe) later.

    > The people who are usually credited with inventing 'modern
    > OO' in form of Smalltalk didn't think of methods as 'subroutines


    Didn't Larry Wall explain that Perl is a postmodern language?

    > without adding intolerable overhead
    > for 1980s hardware' aka 'C++' and all its conceptual descendants.


    For C++ at least, the overhead is not in performance...

    > The reason why I'm refering to this as 'a kludge' is that the sole
    > purpose of an interface declaration is to inform the compiler that two
    > things which aren't different in a certain aspect


    Er... the class declaration would have been enough for that.
    Java interfaces are a kludge because their single motivation
    is to compensate for the lack of multiple inheritance of
    behavior, by breaking the 'everything is a class' principle.

    > 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'...
    [ I usually reserve the word 'ideology' for justifications
    of a de-facto power structure ]
    Paradigms are set to validate conjectures which cannot
    easily be proven, by building up a framework to produce
    testable results, and address known issues.
    Strong typing is one such paradigm. Even if it is not trendy
    nowadays (and is remote to Perl), I believe the question of
    its validity is still open.

    This kind of paradigmatic thinking is imho useful, in the
    same way as as esthetics or morals: it is too hard to fully
    justify every one of one's moves.

    In all respect for your competence, your openness, and your
    bold critical spirit, Rainer.
    Sorry for this out-of-scope discussion (mine, not yours).

    Marc
    Marc Girod, Mar 3, 2013
    #2
    1. Advertising

  3. Rainer Weikusat

    Marc Girod Guest

    On Mar 3, 10:39 am, Marc Girod <> wrote:

    > Right, apart for making overriding possible.


    Sorry, I obviously meant overloading.
    Marc Girod, Mar 3, 2013
    #3
  4. Marc Girod <> writes:
    > Difficult to address 'random remarks'...
    > Especially I cannot do it in the context of Moose::Manual::Concepts
    > which could build up a consistent background: I never used Moose.


    Well, neither did I. This was just an attempt at a criticism of some
    parts of this 'introductory text' I'm especially at odds
    with, motivated by the way in which this text markets[*] 'Moose' as
    must-have solution to problems the author of Moose invented in order
    to solve them (or whose importance he exaggerates greatly ---
    preciously few of the constructors I've written so far didn't contain
    anything except a 'bless' statement and if they did [almost], this was
    usually because object initializion was supposed to be performed by
    some overideable method and in these cases, the 'generic' constructor
    was always inherited from a base class).

    Since there are some point of 'general interest' (to me, at least) in
    your text, I'll try to address them despite this is somewhat off topic
    here.

    [*] 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.

    > On Mar 2, 5:07 pm, Rainer Weikusat <> wrote:


    [making all properties of an object available via 'accessor' methods']

    >> the latter is just a way to accomplish the same as the former with
    >> more overhead.

    >
    > Right, apart for making overriding possible.


    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.

    [...]

    [C++ and "poor men's" message passing]

    >> without adding intolerable overhead for 1980s hardware' aka 'C++'
    >> and all its conceptual descendants.

    >
    > For C++ at least, the overhead is not in performance...


    In C++, a 'virtual method' is one where a call is dispatched at
    runtime by loading a function pointer from a certain slot of the
    'virtual method table' associated with a particular class. That's
    considerably less flexible than 'sending a named message with some
    parameters' to an object which interprets this message by runtime
    analysis: The compiler resolves the name to a vtable slot at
    compilation time and all slots of all applicable vtables are also
    populated at compilation time and remain constant at runtime. This
    is a lot faster than any kind of 'name-based dispatching' with the
    help of a runtime interpreter at the expense of tieing each method to
    a class: There's no way for an unrelated object to act on the same
    message,

    >> The reason why I'm refering to this as 'a kludge' is that the sole
    >> purpose of an interface declaration is to inform the compiler that two
    >> things which aren't different in a certain aspect

    >
    > Er... the class declaration would have been enough for that.
    > Java interfaces are a kludge because their single motivation
    > is to compensate for the lack of multiple inheritance of
    > behavior, by breaking the 'everything is a class' principle.


    except when something like 'interface declarations' come into play:
    This is a way to inform the compiler that unrelated classes do
    actually have a common 'subset of message they can act on' aka
    'compatible methods'. Something similar can be achieved with 'mutiple
    inheritance' but only by introducing relatively awkward (IMO)
    artificial abstractions. An example which came to my mind earlier
    today: Both houses and cars have windows made of glass which can be
    opened and closed. This would be a 'common interface' of these two
    kinds of things. It could expressed with inheritance by defining
    something like an 'intransparent thing with people in it who need/want
    to look outside' class but (IMHO) a car is not something like a house
    or vice versa, they just have some common characteristics, aka 'share
    some set of messages/ methods'.

    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.

    >
    >> 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', as
    in

    ,----
    | Type
    |
    | Hand-written parameter checking in your new() method and accessors.
    |
    | With Moose, you define types declaratively, and then use them by name
    | with your attributes.
    `----

    The possibility that someone wouldn't want to check 'the types of
    arguments passed to his subroutines' doesn't even enter the equation
    here: The only two 'valid' options are 'write code whose sole purpose
    is to compensate for what is regared as deficiency of the language' or
    'use the wonderful "declarative system" which provides all this code
    for free'. But - as I already wrote - I never do that in order to
    force the invocation to fail when 'someone' performed it in a way I
    didn't consider sensible, only if the subroutine should actually
    perform different operations based on the kind of arguments which were
    passed to it. This implies that any object which understands a certain
    set of messages can be used by any code which is also aware of it.
    Rainer Weikusat, Mar 3, 2013
    #4
  5. Ben Morrow <> writes:
    > Quoth Rainer Weikusat <>:
    >>
    >> [*] 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.
    > 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.

    [...]

    >> [making all properties of an object available via 'accessor' methods']
    >>
    >> >> the latter is just a way to accomplish the same as the former with
    >> >> more overhead.
    >> >
    >> > Right, apart for making overriding possible.

    >>
    >> 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: Attributes shouldn't be exposed at
    all. A class should provide methods with some kind of 'useful behaviour',
    both for subclassed and class users and how this behavior is actually
    implemented shouldn't be anybody's business. And I meant that. That's
    called 'encapsulation' and it is generally a good thing because it
    decouples the interface from the implementation.

    I was planning to write a more detailed reply but the lack of
    understanding you've shown here, both about basic OO concepts and the
    two postings I wrote, has made me lose any interest in that.
    Rainer Weikusat, Mar 4, 2013
    #5
  6. Ben Morrow <> writes:
    > Quoth Rainer Weikusat <>:
    >>
    >> [*] 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.
    > 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.

    [...]

    >> [making all properties of an object available via 'accessor' methods']
    >>
    >> >> the latter is just a way to accomplish the same as the former with
    >> >> more overhead.
    >> >
    >> > Right, apart for making overriding possible.

    >>
    >> 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.

    [...]

    >> [C++ and "poor men's" message passing]
    >>
    >> >> without adding intolerable overhead for 1980s hardware' aka 'C++'
    >> >> and all its conceptual descendants.
    >> >
    >> > For C++ at least, the overhead is not in performance...

    >>
    >> In C++, a 'virtual method' is one where a call is dispatched at
    >> runtime by loading a function pointer from a certain slot of the
    >> 'virtual method table' associated with a particular class. That's
    >> considerably less flexible than 'sending a named message with some
    >> parameters' to an object which interprets this message by runtime
    >> analysis:

    >
    > 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'), with a couple of the more weird
    CLOS features added in because the Moose author enjoyed being the
    Seriously Supercool Symbol Table Wizard[tm]. But that's really besides
    the point when discussing message passing semantics for inter-object
    communication.

    >> >> The reason why I'm refering to this as 'a kludge' is that the sole
    >> >> purpose of an interface declaration is to inform the compiler that two
    >> >> things which aren't different in a certain aspect
    >> >
    >> > Er... the class declaration would have been enough for that.
    >> > Java interfaces are a kludge because their single motivation
    >> > is to compensate for the lack of multiple inheritance of
    >> > behavior, by breaking the 'everything is a class' principle.

    >>
    >> except when something like 'interface declarations' come into play:
    >> This is a way to inform the compiler that unrelated classes do
    >> actually have a common 'subset of message they can act on' aka
    >> 'compatible methods'. Something similar can be achieved with 'mutiple
    >> inheritance' but only by introducing relatively awkward (IMO)
    >> artificial abstractions. An example which came to my mind earlier
    >> today: Both houses and cars have windows made of glass which can be
    >> opened and closed. This would be a 'common interface' of these two
    >> kinds of things. It could expressed with inheritance by defining
    >> something like an 'intransparent thing with people in it who need/want
    >> to look outside' class but (IMHO) a car is not something like a house
    >> or vice versa, they just have some common characteristics, aka 'share
    >> some set of messages/ methods'.

    >
    > 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. What I was writing about was the ability to send arbitrary
    messages to object instances which enables unrelated objects to
    provide compatible interfaces if so desired. And this really means
    'unrelated objects', not

    [...]

    >> 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).

    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?" (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.

    [*] Assuming the answer was "I'm a value beef meal", what precisely
    would that mean?

    [...]

    > In my ideal object system there would be no classes; instead every
    > object would specify that it conforms to some list of protocols, and
    > would acquire method implementations from some list of roles, where some
    > of those roles might require the object implement a given protocol
    > before they can be included. It would also include something along the
    > lines of COM's QueryInterface, preferably invoked implicitly to avoid
    > the ridiculous verbosity of typical COM systems, so that an EntishHound
    > object can be treated as a Tree and get an appropriate ->bark for that
    > use, and then be treated as a Dog and get a different appropriate ->bark
    > (C< say "woofrum woofoom" >) for that use.


    This looks like a somewhat informal description of a different
    'general bureacratic schema to classify and organize them all' and one
    which requires even more 'boilerplate declarations' than 'formally
    defined' class hierarchies. I have no experience with that but
    generally, the same objections: This complication isn't necessary and
    I'm strongly inclined to suspect that it is rather psychologically
    than technically motivated. Someone's fear of the unknown is supposed
    to be dealt with by 'controlling everything upfront' (Lest the
    nameless chaos will eat us all, mark my words!).

    That's not how Perl-OO works and I'm quite happy with that.

    >
    >> >> 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).

    > '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
    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.

    >> ,----
    >> | Type
    >> |
    >> | Hand-written parameter checking in your new() method and accessors.
    >> |
    >> | With Moose, you define types declaratively, and then use them by name
    >> | with your attributes.
    >> `----
    >>
    >> The possibility that someone wouldn't want to check 'the types of
    >> arguments passed to his subroutines' doesn't even enter the equation
    >> here: The only two 'valid' options are 'write code whose sole purpose
    >> is to compensate for what is regared as deficiency of the language' or
    >> 'use the wonderful "declarative system" which provides all this code
    >> for free'.

    >
    > If you had actually read the damn documentation instead of jumping on
    > your soapbox to proclaim Stevan Little as the Antichrist


    I haven't proclaimed anyone as anything, despite I've been so
    overbearingly arrogant to use certain quotes from a text I read which
    happened to cast a somewhat-less-than-favorable light onto the people
    who wrote the text I was referring to. I didn't refer to some other
    text you seem to be referring to and if the 'concepts' text I did read
    doesn't describe the thing it is supposed to describe correctly, as
    you're suggesting, that would be another problem with it.

    [...]

    >> But - as I already wrote - I never do that in order to
    >> force the invocation to fail when 'someone' performed it in a way I
    >> didn't consider sensible, only if the subroutine should actually
    >> perform different operations based on the kind of arguments which were
    >> passed to it.

    >
    > 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 !!!"

    Strong-typing advocacy 101.

    [...]

    >> 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.

    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 :).
    Rainer Weikusat, Mar 4, 2013
    #6
  7. Rainer Weikusat <> writes:
    > Ben Morrow <> 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'.
    Rainer Weikusat, Mar 4, 2013
    #7
  8. Ben Morrow <> writes:
    > Quoth Rainer Weikusat <>:
    >> Rainer Weikusat <> writes:
    >> > Ben Morrow <> 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 should 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 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 has 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 :-}.
    Rainer Weikusat, Mar 5, 2013
    #8
  9. Ben Morrow <> writes:
    > Quoth Rainer Weikusat <>:
    >> Rainer Weikusat <> writes:
    >> > Ben Morrow <> 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 :-}.
    Rainer Weikusat, Mar 5, 2013
    #9
  10. NB: I'm trying to ignore sideline issues (such as 'Mindless ad hocery
    is a very common OO design pattern' :) in order to keep this somewhat
    focussed on 'properties of the Perl object model'.

    Ben Morrow <> writes:
    > Quoth Rainer Weikusat <>:
    >> Ben Morrow <> writes:


    [...]

    >> 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'.

    >
    > I don't understand why you seem to think methods which only call other
    > methods (rather than accessing attributes directly) are not part of the
    > 'real class'. AFAIC, a class has a documented public interface; how that
    > interface is implemented is not relevant.


    Because that's how it happens to work in Perl (or in other OO system
    structured around 'message passing'): The only thing which is really
    specific to 'the class' is the object representation it uses. Any of
    these 'methods invoking other methods' will happily work with any
    object which implements the necessary methods, no matter what its
    class happens to be.

    Somewhat stupid contrived example demonstrating that:
    ---------------
    package Teabag;

    sub new
    {
    my $weight;

    $weight = $_[1];
    return bless(\$weight, $_[0]);
    }

    sub weight
    {
    return ${$_[0]};
    }

    sub contents
    {
    return 'tea';
    }

    sub name
    {
    return 'teabag';
    }

    sub unit
    {
    return 'grams';
    }

    sub statement
    {
    printf("The %s contains %s %s of %s.\n",
    $_[0]->name(), $_[0]->weight(), $_[0]->unit(), $_[0]->contents());
    }

    package Gun;

    sub new
    {
    my $weight;

    $weight = $_[1];
    return bless(\$weight, $_[0]);
    }

    sub weight
    {
    return ${$_[0]};
    }

    sub contents
    {
    return 'gunpowder';
    }

    sub name
    {
    return 'gun';
    }

    sub unit
    {
    return 'pounds';
    }

    package main;

    my $gun = Gun->new(3.5);

    Teabag::statement($gun);
    ------------

    [...]

    >> 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.

    >
    > OK, so how would you implement the 'charge' function, in Perl? As a
    > plain function? That works for the case where there is only one possible
    > charge calculation, but what if I also have other types of object with
    > different charging rules?


    I was refering to the specific example you posted, not to any
    conceivable other example you could have posted instead: The 'charge'
    function has a single input, namely, 'an object', and the only
    requirements for this object are 'it has to implement the price and
    discount methods' and not 'it must be a book' (or its class must have
    been derived from the 'Book' class). By putting this charge function
    into the 'Book' package, you're actually just expressing your opinion
    that it should only be used for 'Book objects' but this voluntary
    reduction in 'general usefulness' is neither technically required nor
    necessarily sensible (since the same 'charging rules' could be applied
    to other objects-for-sale as well).

    [...]

    > One of the things Moose makes easy is moving code like this into roles.
    > That means that otherwise-unrelated classes can consume the role in
    > order to reuse the code.


    As I've shown with my 'silly example' above, otherwise-unrelated
    classes can 'reuse the code' without any mechanism for doing so if the
    code isn't really dependent on something which is specific to a
    particular class. And the 'set of messages' objects of a class
    understand isn't.

    [...]

    >> I'll try to contrast this with a real example (somewhat simplified):

    > [...]
    >> 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 :-}.

    >
    > I didn't entirely follow the bit I snipped, but I don't think it was
    > really relevant (please correct me if I'm wrong). I believe all you were
    > saying is that, had you chosen to subclass Interest, you could have done
    > so without needing to know anything about where it kept its attributes;
    > but you didn't explain how you would have achieved that.


    That was actually a half-way ill thought out afterthought and the
    'main' part of the statement was what you snipped. This was supposed
    to be the smallest example of 'a real class' I could come up with which
    provides 'behaviour' to its users (and whose instances need to keep
    'state information' 'in some way' in order to provide this behaviour)
    and not 'a panhandle to a set of named attributes'.
    Rainer Weikusat, Mar 6, 2013
    #10
  11. Ben Morrow <> writes:
    > Quoth Rainer Weikusat <>:
    >> Ben Morrow <> writes:
    >> > Quoth Rainer Weikusat <>:
    >> >> Ben Morrow <> writes:

    >>
    >> [...]
    >>
    >> >> 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'.
    >> >
    >> > I don't understand why you seem to think methods which only call other
    >> > methods (rather than accessing attributes directly) are not part of the
    >> > 'real class'. AFAIC, a class has a documented public interface; how that
    >> > interface is implemented is not relevant.

    >>
    >> Because that's how it happens to work in Perl (or in other OO system
    >> structured around 'message passing'):

    >
    > Perl's OO system is not particularly structured around message passing,
    > in the Smalltalk sense.It's actually not that easy to create an object
    > which accepts arbitrary messages and (say) passes them on to some other
    > object, especially if you want ->can and so on to work properly on the
    > proxy.


    It is also not particularly 'structured around message passing' in the
    'Royal Mail' sense and 'we' haven't even considered the possibility that
    'message passing' could also refer to Mr Message fainting or dying,
    just with a trivial misspelling. There are any number of possible
    interpretations of any word or combination of words I wrote which make no
    sense and you've ably demonstrate that you're capable of finding them.

    >>> The only thing which is really specific to 'the class' is the
    >>> object representation it uses. Any of
    >>> these 'methods invoking other methods' will happily work with any
    >>> object which implements the necessary methods, no matter what its
    >>> class happens to be.

    >
    > Hmm. It sounds to me as though you are the one trying to turn objects
    > into fancy structs.


    Because of some properties of an example you invented?

    > One of the points of OO is method dispatch or
    > polymorphism or whatever you want to call it: that you can send the same
    > message to different objects and they will behave differently. The only
    > (reasonable) ways to achieve that in Perl are to put the method
    > implementations directly into the class concerned, or to put them into a
    > superclass.


    This is another point which - so far - hasn't been discussed and isn't
    relevant.

    >
    >> Somewhat stupid contrived example demonstrating that:
    >> ---------------
    >> package Teabag;
    >>
    >> sub new
    >> {
    >> my $weight;
    >>
    >> $weight = $_[1];
    >> return bless(\$weight, $_[0]);
    >> }
    >>
    >> sub weight
    >> {
    >> return ${$_[0]};
    >> }
    >>
    >> sub contents
    >> {
    >> return 'tea';
    >> }

    >
    > I take it you consider these constants to be part of the internal
    > representation of the object?


    I consider this sufficient in the context of a simple example
    demonstrating what I intended to demonstrate: Subroutines which don't
    do anything with objects except 'invoke some methods' can work with
    any Perl object, its class notwithstanding.

    >>
    >> [...]
    >>
    >> >> 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.
    >> >
    >> > OK, so how would you implement the 'charge' function, in Perl? As a
    >> > plain function? That works for the case where there is only one possible
    >> > charge calculation, but what if I also have other types of object with
    >> > different charging rules?

    >>
    >> I was refering to the specific example you posted, not to any
    >> conceivable other example you could have posted instead:

    >
    > You didn't answer the question:


    The answer is irrelevant for the properties of your contrived example
    I wrote about.

    > Now suppose I have a different situation. I have Book and Book::InSeries
    > objects as before, which should use this charge function:
    >
    > sub charge {
    > my ($self, $count) = @_;
    >
    > my $price = $self->price;
    > my $discount = $self->discount;
    >
    > $count * ($price - $price * $discount);
    > }
    >
    > In the Book case, ->price and ->discount are properties; in the InSeries
    > case, they are taken from the object's ->series property. I also have
    > Bulk objects, which should use this charge function:
    >
    > sub charge {
    > my ($self, $count) = @_;
    >
    > my $base = $self->price;
    > my $discount = $self->discount;
    > my $cutoff = $self->cutoff;
    >
    > my $price = $count > $cutoff ? $base * $discount : $base;
    > $count * $price;
    > }
    >
    > How would you implement these three classes? (I am genuinely interested
    > in your answer to this question.)


    And I'm not interested in createing a string of different
    explanations trying to match the speed at which you can come up with
    new contrived examples which have been 'constructed' such that the
    previous explanation isn't applicable to them anymore because this is
    just an endless chase of a goalpost which keeps being moved.

    "Wer Ohren hat, der hoere. Wer nichts hoeren will der laessts
    halt". Pax Hibiscus.
    Rainer Weikusat, Mar 6, 2013
    #11
  12. Rainer Weikusat <> writes:

    [...]

    > It is also not particularly 'structured around message passing'


    In case this seems a little harsh to someone: Considering that this is
    the 2nd "Let's move elsewhere!" posting, I'm assuming that this is
    mainly an attempt at talking circles around me in order to obscure a
    point instead of a discussion intended to clarify one. Since this
    cannot possibly lead anywhere, I see no reason to engage in it.
    Rainer Weikusat, Mar 6, 2013
    #12
  13. Rainer Weikusat

    Steve May Guest

    On 03/06/2013 03:33 PM, Ben Morrow wrote:
    >
    > Quoth Rainer Weikusat <>:
    >> Rainer Weikusat <> writes:
    >>
    >> [...]
    >>
    >>> It is also not particularly 'structured around message passing'

    >>
    >> In case this seems a little harsh to someone: Considering that this is
    >> the 2nd "Let's move elsewhere!" posting, I'm assuming that this is
    >> mainly an attempt at talking circles around me in order to obscure a
    >> point instead of a discussion intended to clarify one. Since this
    >> cannot possibly lead anywhere, I see no reason to engage in it.

    >
    > Let's recap, shall we?
    >
    > - This subthread started with my assertion that, in Perl, attributes
    > should always be wrapped in accessor methods, since that makes
    > subclassing easier;
    >
    > - you found this concept 'mind-boggling', since apparently you
    > believe that methods which only call other methods should not be
    > part of a class (you have yet to explain where you think they
    > *should* go...);
    >
    > - I asked you to explain this belief;
    >
    > - your explanation was that 'that's how it happens to work in Perl
    > (or in other OO system structured around 'message passing')';
    >
    > - I pointed out that Perl's OO is not particularly structured around
    > message passing, at least not as I understand the term; I also
    > pointed out that since Perl doesn't have generics or multimethods
    > there isn't anywhere to put functionality related to a class of
    > objects *except* in the class.
    >
    > I don't think I'm the one talking in circles.
    >
    > Ben
    >


    Ben,

    I've been following your posts in this thread and for what it's worth
    you've managed to clarify a few perlish OO concepts for me, at least.

    Thanks,

    Steve
    Steve May, Mar 7, 2013
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. MattB

    remarks in Intellisense

    MattB, Sep 7, 2004, in forum: ASP .Net
    Replies:
    6
    Views:
    2,190
    Greg Burns
    Sep 7, 2004
  2. Replies:
    6
    Views:
    1,290
    Gennaro Prota
    Jun 28, 2007
  3. Michael S. Scherotter

    <remarks/> in proxy classes

    Michael S. Scherotter, Feb 15, 2006, in forum: ASP .Net Web Services
    Replies:
    0
    Views:
    116
    Michael S. Scherotter
    Feb 15, 2006
  4. Trans
    Replies:
    0
    Views:
    148
    Trans
    Apr 23, 2006
  5. Tim McDaniel
    Replies:
    4
    Views:
    136
    Ted Zlatanov
    Jan 2, 2009
Loading...

Share This Page