问题
I'm trying to extract some constants from a Perl file which I've defined in file A.pm
package A;
use constant ERROR_ID_MAP => [
PLAYBACK_ERROR => {
defaultMessage => "Sorry there was an error with a playback",
errorCode => 0,
},
PURCHASE_ERROR => {
defaultMessage => "Sorry, we've encountered a problem with purchasing. Please try again.",
errorCode => 2123,
},
];
and so on...
then in package B, I want to get that error file somehow. My thought was to get it like:
sub getErrorMap {
my ($self) = @_;
my $map = A::ERROR_ID_MAP;
# Iterate through the array / hash and get the error's default message etc.
}
But this doesn't seem to work. The other option is to make package A into a class and perhaps return the constant? (In package A):
sub new {
my ($class, $args) = @_;
my $self;
bless($self, $class);
return $self;
}
sub getErrorConstants {
my $self = @_;
return ERROR_ID_MAP;
}
Is there an easier way to do this perhaps to just get all the data inside ERROR_ID_MAP without going through this trouble, so we almost treat package A as a configuration file of sorts?
NOTE - hopefully there's not too many errors in the code above that will take away from the point of the question.
回答1:
You should write a module, say Definitions.pm, that uses Exporter, like this
Definitions.pm
package Definitions;
use strict;
use warnings;
use base 'Exporter';
our @EXPORT_OK = qw/ ERROR_ID_MAP /;
use constant ERROR_ID_MAP => [
PLAYBACK_ERROR => {
defaultMessage => "Sorry there was an error with a playback",
errorCode => 0,
},
PURCHASE_ERROR => {
defaultMessage => "Sorry, we've encountered a problem with purchasing. Please try again.",
errorCode => 2123,
},
];
Then you can just use Definitions and specify the constants that you want to import in your main code, like this
main.pl
use strict;
use warnings;
use Definitions qw/ ERROR_ID_MAP /;
use Data::Dump;
dd ERROR_ID_MAP;
output
[
"PLAYBACK_ERROR",
{
defaultMessage => "Sorry there was an error with a playback",
errorCode => 0,
},
"PURCHASE_ERROR",
{
defaultMessage => "Sorry, we've encountered a problem with purchasing. Please try again.",
errorCode => 2123,
},
]
回答2:
While @Borodin's answer may look like it is doing what you want, be aware that there is nuance to constant.pm as the following example demonstrates:
#!/usr/bin/env perl
use strict;
use warnings;
use YAML::XS;
use constant X => [ { test => 1 }];
print Dump X;
X->[0]{test} = 3;
print Dump X;
Output
$ ./zxc.pl --- - test: 1 --- - test: 3
use constant X => [ ... ] means the constant subroutine always returns the same reference. However, you can manipulate the elements to which that reference points. If you truly want to export constants, consider using Const::Fast:
Definitions.pm
package Definitions;
use strict;
use warnings;
use Const::Fast;
use Exporter qw( import );
our @EXPORT = qw();
our @EXPORT_OK = qw( $ERROR_ID_MAP );
const our $ERROR_ID_MAP => [
PLAYBACK_ERROR => {
defaultMessage => "Sorry there was an error with a playback",
errorCode => 0,
},
PURCHASE_ERROR => {
defaultMessage => "Sorry, we've encountered a problem with purchasing. Please try again.",
errorCode => 2123,
},
];
main.pl
!/usr/bin/env perl
use strict;
use warnings;
use YAML::XS;
use Definitions qw( $ERROR_ID_MAP );
print Dump $ERROR_ID_MAP;
$ERROR_ID_MAP->[1]{errorCode} = 3;
Output:
--- - PLAYBACK_ERROR - defaultMessage: Sorry there was an error with a playback errorCode: 0 - PURCHASE_ERROR - defaultMessage: Sorry, we've encountered a problem with purchasing. Please try again. errorCode: 2123 Modification of a read-only value attempted at ./main.pl line 11.
Notice how an attempt to change an element of the data structure to which $ERROR_ID_MAP refers causes a helpful exception.
回答3:
For this to work, you need to put
use A;
in B.pm
来源:https://stackoverflow.com/questions/27388828/getting-constants-from-another-file-in-perl