Thanks for your interest!
What am I trying to do?
I'm hesitating a bit telling about it, since I don't think "perl folks" will like what I try to implement. This is by no means meant as an offence, rather shall indicate me being one of those "refugees from another language" (mainly Java, in my case) who's trying to make perl work in a non-perlish way!
;-)
Nevertheless, I'll try to explain:
Implementing a little "bigger" piece of software in perl (Yes, I'm also using modules, objects, and inheritance! Who guessed? Some of the my Java leftovers... (-; ), I have had repetitive problems with my parameter passing to my functions, some of it caused by perl's autovivificating nature when passing misspelled hashes, some by me getting confused with all your perl's $, @, %, references and the like. Besides that, some of the function lists with multiple parameters started getting obfuscated, thus I decided to use "named parameters", i.e. passed my arguments aligned with their name and "processed" them in a local parameter hash.
I hope you won't fall off your seats when reading the following code (being completely Java style, I know, probably being a sin using perl builtins with paranthesis also), but in case you feel any masochistic drive inside your personality...:
sub new {
# parameters:
# [$this],
# @attributes: tree, messageNum, messageText
my ($this, @attributes) = @_;
# "process" optional attributes
my %attributes = (
tree => undef,
messageNum => undef,
messageText => undef,
@attributes,
);
# assert for valid argument list
if ((keys %attributes) > 3) {
die "invalid argument list during function call!\n";
}
# assert mandatory parameters
my $tree = $attributes{tree};
my $messageNum = $attributes{messageNum};
my $messageText = $attributes{messageText};
if ((!defined($this)) || (!defined($tree)) || (!defined($messageNu
+m))) {
die "invalid argument list during function call!\n";
}
The first assertion is supposed to tell me whether I misspelled one of the parameter names (which simply would be "ignored" otherwise), the second is to check whether the mandatory parameters truly have been passed as arguments and correctly been set (okay, at this point you might want to ask why I don't rather try to treat my senility than trying to make perl a nurse. But I told you I didn't want to tell in the first place, didn't I?).
Since this piece of code is quite repetitve, I tried to automate it some, i.e. especially trying to make the creation of my local arguments easier, and came up with the follwing:
sub new {
# parameters:
# [$this],
# @namedParameters: tree, messageNum, (messageText)
##### process parameters #####
my ($this, @namedParameters) = @_;
# process named parameters (with default values)
my ($tree, $messageNum, $messageText) = assertNamedParameters([
numNamedParameters => 3,
tree => undef,
messageNum => undef,
messageText => undef,
], \@namedParameters
);
# check mandatory paramters
assertValueIsDefined($this, $tree, $messageNum);
The assertNamedParameters may seem a little bit odd and misformated (okay, I'm not quite finished with my code cleanup). The intention is to define the valid parameter list and provide default values for each of it (so passing them CAN be optional).
If of any interest, the function itself looks like this:
sub assertNamedParameters {
# parameters:
# $parametersRef, $argumentsRef
my ($parametersRef, $argumentsRef) = @_;
# check passed arguments
assertValueIsDefined($parametersRef, $argumentsRef);
# create parameter hash
my %parameters = (
@{$parametersRef},
@{$argumentsRef},
);
# get valid number of parameters
if (!exists($parameters{numNamedParameters})) {
assertThrowException(
"parameter key ('numNamedParameters') has not
been defined in passed parameter hash");
}
# get number of parameters
my $numNamedParameters = $parameters{numNamedParameters};
# assert for valid parameter count
if ($numNamedParameters < 1) {
assertThrowException(
"invalid number of parameters ($numNamedParameters) specif
+ied
(minimum is one parameter)");
}
# assert parameter list for valid parameter count
# (account for the numParameters key itself (!))
if ((keys %parameters) != ($numNamedParameters + 1)) {
assertThrowException(
"invalid number of parameters ($numNamedParameters) passed
+");
}
# return parameter values
my ($parameterName, $parameterValue, @parameterValues);
# retrieve each given parameter
# (skipping 'numParameters' key)
for (my $i = 1; $i <= $numNamedParameters; $i++) {
# retrieve parameter name from parameter list
# IN ORDER concerning given parameter list!
$parameterName = $parametersRef->[2*$i];
# get parameter value from parameter hash
$parameterValue = $parameters{$parameterName};
push(@parameterValues, $parameterValue);
}
return(@parameterValues);
}
The aim is to return the arguments in the order specified by caller, thus being passed into his local variable correspondingly.
(Here's where the question starts:)
What I thought of now (and what originated my question) was to simply return an code string setting up the named parameter variables and it's according values, with the caller then simply eval's.
I hope I could explain what I'm trying to do (please don't ask me WHY I would want to do that, probably my medication just has been wrong today, or I simply smoked something REAL good! (-; ), thus I wonder if it can be done in any handy way?
A last comment to answer the surely upcoming question in advance: I HAVE TO use perl for programming this application, otherwise I surely wouldn't try to abuse it, but programming in some language I'm more used to.
And I'm concerned with some rather complex data structures including trees with doubly linked (and cached) leafs, this subtle errors in the parameter passing are hard for me to loacte and debug.
So, if anybody had the patience and mercifulness to read ALL THIS, be assured my heart felt thanks! I'd be glad to hear anything!
P.S.
I hope my english is understandable. Greeting from Germany!
|