Napísal som malú triedu, ktorá má nejaké metódy getter a setter. Jednou z týchto vlastností je hash.
sub getMyData
{
my $objekt = shift;
return $objekt->{MYDATA};
}
sub setMyData
{
my $objekt = shift;
my %myData= shift;
$objekt->{MYDATA} = %myData;
}
Ak nastavím hodnotu, ako je táto, v inom skripte, ktorý pristupuje k mojej triede:
my %test;
$test{"apple"}="red";
$objekt = MYNAMESPACE::MYCLASS->new;
$objekt->setMyData(%test);
Myslel som, že k tejto hodnote môžem pristupovať jednoduchým spôsobom:
my $data = $objekt->getMyData;
print $data{"apple"};
Len som si undef hodnotu.
Môže mi niekto povedať, čo je tu zle a ako môžem pristupovať k getMyData a vytlačiť hodnotu "red"?
odpovede:
3 pre odpoveď č. 1Chýba vám šípka dereferencie. Pretože si dal hashref (%myData
), dostanete aj odkaz.
my $data = $objekt->getMyData;
print $data->{"apple"};
# ^
# here
Musíte tiež zmeniť priradenie, pretože odovzdávate zoznam nastavovateľovi, nie referenciu. shift
je pre skalárne (jednoduché) hodnoty, ale %test
sa zmení na zoznam (mnoho hodnôt).
sub setMyData
{
my $objekt = shift;
my %myData = @_;
$objekt->{MYDATA} = %myData;
}
Existuje však niekoľko ďalších problémov s vaším kódom.
4 pre odpoveď č. 2
shift
odstráni a vráti najprv prvok poľa. Vnútri podprogramu funguje holý posun @_
, ktorá obsahuje kópiu všetkých argumentov odovzdaných tomuto podprogramu.
Čo sa tu naozaj deje, je to setMyData
odovzdáva tieto údaje:
setMyData($objekt, "apple", "red");
- Prvý
shift
vsetMyData
odstraňuje$objekt
z@_
- Druhy
shift
vsetMyData
odstráni "jablko", ale pretože výsledok tohto posunu priradíte k Hash, vytvorí Hash, ktorý vyzerá takto:"apple" => undef
- Beriete odkaz na tento hash a uložte ho do MYDATA kľúča
$objekt
Čo naozaj chcete, je priradiť zvyšok @_
do Hašu:
sub setMyData {
my $objekt = shift;
my %myData = @_;
# my ($objekt, %myData) = @_; (alternative)
$objekt->{MYDATA} = %myData;
}
Ďalšou možnosťou je namiesto toho poslať Hash odkaz na setMyData
, ktoré by som pracovať s shift
:
sub setMyData {
my $objekt = shift;
my $myData_ref = shift
$objekt->{MYDATA} = $myData_ref;
}
$objekt->setMyData(%test);