Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • [When] the computer can find potential problems -- particularly when it's close to compile time -- this is far better than requiring the programmer to always look for those potential problems.

    This is not a case where the computer can identify problems with certainty. The compiler cannot judge your intent. Did you make a typo in the name of a class-local method such that it collides with the name of a composed method? Did you forget to read the documentation? Did you do it deliberately? Did someone up

    • Please note that I'm not trying to change your opinion here because it's obvious that we strongly disagree here. I provide this for anyone else who may be reading this.

      This is not a case where the computer can identify problems with certainty. The compiler cannot judge your intent.

      And that's why the warning is so desperately needed. If I inherit from A and B and both provide a "foo" method, I usually get the one that I've inherited from first. One could argue that I forgot to read the documentation or that I did it deliberately, but just like the composition problem I list above, there's no way that the compiler can know this, so it should warn, but with MI, it doesn't and things silently break. We have a way out of this trap with roles.

      Did you make a typo in the name of a class-local method such that it collides with the name of a composed method?

      If I write a method that accidentally collides with another method, it implies that I'm adding behavior and not trying to override behavior. Thus, a warning is warranted because what I'm doing doesn't match what I want to do.

      Did you forget to read the documentation?

      I'm particularly keen on focusing on real-world usage here. Documentation is often incomplete. Developers often don't read documentation. Developers (especially me!) often miss crucial bits of documentation. Sometimes I read the documentation several months ago and have heavily used the code and am not aware that it's changed. We are approaching 600 packages and no, I don't remember all of them and having to reread their docs every single time I work with them is not an option. I have to get stuff done. Having a feature that hopes that even conscientious developers haven't made a mistake is wrong.

      Did you do it deliberately?

      Did I do what deliberately? If you mean "override the method", then this implies I knew the method was there and explicitly excluding it takes about two seconds and let's other developers come along and instantly see that there's an excluded method. This is a benefit because it increases the readability of the code.

      Did someone upgrade a role and not tell you?

      The I absolutely want that warning! That means that someone else is trying to add behavior and that behavior is presumably desired instead of silently ignored! This is probably the strongest argument in favor of a warning.

      The compiler has no way of divining my intent, so the compiler should say "hey, I'm not sure what you meant here, would you please be explicit?"

      And your "slurp a file into an array" argument is completely different. You're not losing information there. You are losing information when you silently override a method. Please provide an example where we silently discard information for a better comparison. So many languages struggle with class composition issues and get it wrong repeatedly. I don't want to see that happen with roles.

      I've worked with you before and I know you're a good enough programmer that it's quite possible that many of these issues don't apply to you. For me, I work with poorly documented code. I forget about methods in documentation I've read before. I update code and run my test suite and don't notice that there's a corner case I've missed. My code's not perfect and I want the language to help me out when it sees something that it knows is dodgy and is trivial to fix. The added benefit is that every programmer subsequently maintaining that code can explicitly see what's going on. That's a joy we often don't see in dynamic languages.

      • If you mean "override the method", then this implies I knew the method was there and explicitly excluding it takes about two seconds and let's other developers come along and instantly see that there's an excluded method. This is a benefit because it increases the readability of the code.

        Yet when I override multiple methods (or all of the methods) from a role for the purpose of complete allomorphism or delegation, your approach means that I have to exclude every one of them explicitly, which is mere busy

        • For the case of overriding everything or almost everything and the role is not simply an interface, then yes, the work to exclude all of the role's methods would be annoying. That's the only interesting argument I've heard from this entire discussion and had the discussion started out with this, then things might have gone easier.

          The problem is that your solution is still throwing away information, my solution can be cumbersome at times. So the reality is that this is a syntax issue. If a good, clean syn

          • If a good, clean syntax were found which makes overriding a role's methods explicit and non-cumbersome but still warns about ambiguity, then both concerns can be addressed.

            mst has some very nice examples using MooseX::Declare, where you provide a block after applying a role. Any method you define in that block very obviously takes precedence over methods composed from the role.

            ... your solution of ignoring the real, existing, many hours of debugging problem that we've had at the BBC trying to find those

        • Hmm maybe we need some examples here. I am just starting to use Moose, so I must be missing something, but I cannot imagine someone wanting to override all methods of a used role.
          • I can easily imagine this. If you simply want to say "I provide this behavior" but your implementation differs significantly, you might override all of the roles (this is different from an interface because the role can also provide an implementation). The issue is that this is the use case that chromatic wants to support and I'm against silently discarding behavior.

            • I don't understandy why to declare "I provide this behaviour" someone would use a Role. Maybe it comes with more practice - that is why I ask for concrete examples.
              • Let's say that you can serialize an object as HTML. You might use the role Role::Serializable::HTML with a &serialize method. Then someone can ask:

                if ( $object->DOES('Role::Serializable::HTML') ) {
                    print $object->serialize;
                }

                By providing a name for the behavior, you are guaranteeing to someone that you provide a &serialize method and that it will serialize the object as HTML.

                However, and this is chromatic's concern, it's quite reasonable that the object might want to use that r

              • I've written a lot of mock objects, and I've had to work around a lot of code which performs its own type checking. That can interfere with the work of mock objects. I plan to write an article with more concrete examples soon, but for now I hope it's not too abstract to say that the question "Is this entity a member of an inheritance hierarchy at this point or lower?" is much less interesting and much more difficult than the question "Does this entity perform the behavior I expect?"

        • Tell me with a straight face that it's not crazy to apply a role to a class and then immediately list all of the methods you don't want to compose from the role into the class because they appear in the class immediately after the role application.

          Tell me with a straight face that it's not crazy to use a module and then be forced to list all of the methods that you want to import because it didn't define @EXPORT. Particularly when the only reason why someone would want to use that module is to get access t

          • Tell me with a straight face that it's not crazy to use a module and then be forced to list all of the methods that you want to import because it didn't define @EXPORT. Particularly when the only reason why someone would want to use that module is to get access to those functions.

            The important difference is that roles have always had the explicit design goal of not enforcing any particular implementation decision to take advantage of them.

            • The fact that someone has a legitimate design goal that creates action at a distance doesn't necessarily make the decision to create action at a distance a good idea.

              In a similar spirit I would not be opposed to an optional warning if my subclass overrode a parent class's method and didn't, say, provide an attribute that says, "Yes, this is an intentional override, don't warn." You might find having to type :override annoying, but I would find it invaluable. (I also know that I have a snowball's chance in

              • I believe it's easier to argue that inheriting or composing in methods is more action at a distance than declaring them locally. Perhaps prototype OO systems are clearest by this metric.