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.
  • The right way to do this would be Replace Conditional With Polymorphism… that is, if feasible/sensible, wrap the objects in other objects which all have a stringify method that delegates to the right method in the wrapped object.

    But doing it for just this one instance, of course, is way too much effort.

    And I find that can is often the wrong tool when I’m just trying to do something, regardless of how it gets done. Usually, eval is better suited to that job, although in this case it is so unw

    • Courtesy of Matt Trout here is an evil trick to enables a different kind of syntax…

      sub try::method {
          my $self = shift;
          for my $method ( @_ ) {
              return \sub { $self->$method( @_ ) } if $self->can( $method );
          }
          my $class = ref( $self ) || $self;
          croak qq{Can't locate any of the object methods "@$methods" via package "$class"};
      }

      return [
          map  { $_->${try::method qw(string heredoc)}() }
          map  { @$_ }
          grep { defined }
          map  { $doc->find( $_ ) }
          qw( Token::Quote Token::HereDoc )
      ];
      • When I wrote App::Pgrep, I chose a different route. I have a hash which resembles this (there are other keys in the hash which I've removed for clarity):

        %HANDLER_FOR = (
            quote   => { stringify => sub { shift->string } },
            heredoc => {
                stringify => sub {

                    # heredoc lines are terminated with newlines
                    my @strings = shift->heredoc;
           

        • Hmm, I seem to remember muttering something to do with polymorphism on this thread…

          sub TokenHandler::quote::stringify { shift->string }

          sub TokenHandler::heredoc::stringify {
              # heredoc lines are terminated with newlines
              my @strings = shift->heredoc;
              return join '' => @strings;
          }

          sub TokenHandler::pod::stringify {
              # pod lines lines are *not* terminated with newlines
              my @strings = shift->lines;
              return join "\n" =

          • I was going to change the code when I remembered why I didn't go this route: I didn't want to add code directly to the classes. What if Adam adds a stringify method? What if I forget one and there's some crazy AUTOLOAD method? What if at some point in the future I wanted to swap in a class with an identical interface? By adding just a tiny bit of infrastructure, I can sidestep these issues. I wasn't terribly worried about them in the specific case of PPI, but in the general case, I'm extremely gun shy

            • What if Adam adds a stringify method?

              Huh? What does that have to do with the code I wrote?

              • Again, it's probably not an issue with the particular example in hand, but if I add methods directly to a class and someone else comes along and adds identically named methods, I have no guarantee that my method will behave the same way their method does. When their other methods try to call the method and get mine, who knows what happens?

                Thus, I really don't feel comfortable reaching directly into another package (though traits are OK because you (mostly) get the compile-time safety).

                • I’m trying to follow what you are talking about. Who else than you would be adding methods to your own classes?

                  • Ah, sheesh. Now I see the disconnect. I skimmed your code (thinking that I had already seen stuff like this before) and I had read TokenHandler::pod::stringify as PPI::Token::Pod::stringify. Just shoot me now, will you? I was surprised that you had suggested this. Now I know why :)

                    • Ah, now it makes sense.

                      Yeah, I definitely would not suggest that! (Considering how much I lambast the Ruby crowd for making a mindless habit of it…)

                      I just thought that, well, you need a dispatch at that point, and your table is static, so why not let Perl do the job? I find the resulting code a good deal less ugly too, although that is certainly debatable.