Pergunta

I have two Perl classes. Let's call one Client, the other Server. Server is a well defined Moose class. Client is not a Moose class, and is just a very thin facade to connect to a Server object over a network.

Furthermore, Client is internal to our project and shouldn't be used by anyone else. Now at our company, other developers cannot always be trusted. To help notify them that they're doing something wrong, our Client class has a custom import statement:

package Client;

sub import {
    my ($self, $promise) = @_;
    die "this is not a public API"
        unless $promise eq "Only CertainTeam should be using this API";
}

sub do_something { ... }

So in order for someone to use Client, they would have to type:

use Client q{Only CertainTeam should be using this API};

I'm not sure if this is the best approach, but it has worked nicely in deterring other teams from using Client. I'd now like to make Client a Moose class. However, perl is pretty unhappy when I add use Moose;, as I am now overriding Moose's import. I get the following error:

Prototype mismatch: sub Client::with: none vs (&;$) at Client.pm line 14

Anyone have any ideas on how I can persist the import behavior of Client while making it a Moose class?

Foi útil?

Solução

This error message has nothing to do with your import method. You are not overriding an import method that Moose has installed into your class, because Moose doesn't install any such method into your class.

It is because Moose exports a function called with, but your package already contains a function called with. At a guess, you're using the venerable Error.pm for exception handling; that exports a function called with. This is a known incompatibility.

My suggestions:

  • Error.pm is no longer recommended by its maintainers. For try/catch, switch to Try::Tiny.
  • The Error::Simple base class for exceptions is part of the same distribution as Error.pm. Consider switching to Throwable::Error.
  • This import method seems like a pretty weird attempt at security. How about renaming the Client class something like CertainTeam::Internal::Client? While this wouldn't stop other people using it, anybody who litters their code with references to what is clearly another team's internal client is inviting trouble. The only guarantee they get is that if their code breaks, they can keep both halves.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top