[perl] Spookwaarde in funktie-argument

Pagina: 1
Acties:

  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 13-09 23:09
Ik heb in een class/module in Perl het volgende staan :
code:
1
2
3
4
5
6
7
8
9
10
11
12
sub buildShopsArgument {

if ($_[0] == 0) {
      $shops_argument = "shops";
} else {
      $shops = join(",", @_);
      $shops_argument = "(SELECT * FROM shops WHERE id IN ($shops)) AS shops";
}

return $shops_argument;

}

Als ik nu de funktie aanroep met
code:
1
2
@arr = (1, 4 ,5 ,6);
print $report->buildShopsArgument(@arr);

Lijkt hij goed te werken, maar ik kreeg ook een of andere spookwaarde en ik kom er niet uit waar die vandaan komt.

De output is namelijk
code:
1
(SELECT * FROM shops WHERE id IN (Report=HASH(0x80f630c),1,4,5,6)) AS shops

Ik vermoed dat die waarde eoa interne variabele is, maar wat doe ik nu fout. Zowieso vind ik die perl-array's maar een beetje wazig.

SIZE does matter.
"You're go at throttle up!"


  • tomato
  • Registratie: November 1999
  • Niet online
Moet je niet @_[0] gebruiken?

  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 13-09 23:09
Op dinsdag 29 januari 2002 13:15 schreef tomato het volgende:
Moet je niet @_[0] gebruiken?
Dat dacht ik eerst ook nog, maar dan krijg je het volgende :
code:
1
(SELECT * FROM shops WHERE id IN (Report=HASH(0x80f630c))) AS shops

SIZE does matter.
"You're go at throttle up!"


Verwijderd

Bij een method-aanroep ($report->hjldksjdl) wordt het object zelf ($report) als eerste argument doorgegeven. wat je als eerste nog even moet doen in je subroutine is
code:
1
my $self = shift;

sowieso kan je de subroutine beter zo schrijven:
code:
1
2
3
4
5
6
7
8
9
10
11
12
sub buildShopsArgument {
   my $self = shift;

   my $shops_argument = 'shops';

   if (@_) { # als er nog meer argumenten zijn
    my $shops = join(",", @_);
    $shops_argument = "(SELECT * FROM shops WHERE id IN ($shops)) AS shops";
   }

   return $shops_argument;
}

  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 13-09 23:09
Bij deze benoem ik nonomen tot "Held van de dag" *D

Bedankt!

Ik vond het al heel wat dat die funktie het uberhaupt deed (voor een week oude perln00b)

SIZE does matter.
"You're go at throttle up!"


  • tomato
  • Registratie: November 1999
  • Niet online
Inderdaad, wat nonomen zegt is juist. In @_[0] zit nu het object zelf (instantie van Report) zodat de methode weet op welk object hij werkt.
Wanneer je een object als scalar wilt printen zal hij de classe geven en wat informatie over de geheugenlocatie (wat je dus helemaal niet wilt hebben, daarom shift je de argumenten eerst).

Verwijderd

Een andere reden om het object (of eigenlijk een reference ernaartoe) naar een variabele te shiften en niet gewoon weg te halen is dat je op die manier in de subroutine/method nog andere object-methods kan aanroepen op het zelfde object.

  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 13-09 23:09
Dank voor de supersnelle replies..

Toch nog een volgend vraagje..

Ik wil aan een funktie "Build" twee parameters meegeven. Elk van deze parameters is op zichzelf een @array, dus :
code:
1
print &Build (@arr1, @arr2);

In "Build" moeten er verschillende dingen mee gebeuren. Ik dacht nu slim te zijn en doe het volgende :
code:
1
2
3
4
5
6
sub Build {
   my $self = shift;
   my $first = 1;

   my @vendors = shift;
   my @omzetgroepen = shift;

Eerst $self erafhalen en daarna de twee arrays in een lokale variabelen zetten. Maar in @vendors staat nu het eerste element van de eerste parameter en in @omzetgroepen de tweede.

SIZE does matter.
"You're go at throttle up!"


Verwijderd

Op zich is je gedachte goed, maar wat er gebeurt wanneer je een gewone array als element van een array geeft, is dat hij er onderdeel van wordt, dus @_ in de sub Build is nu een hele grote array met alle element van @arr1 en @arr2.

Een makkelijke manier om dit te voorkomen is door de arrays als array-references door te geven:
code:
1
print $report->Build(\@arr1, \@arr2);

Alleen moet je dan niet vergeten ze in de sub te dereferencen:
code:
1
2
3
4
5
6
sub Build {
   my $self = shift;
   my $first = 1;

   my $vendors = shift;
   my $omzetgroepen = shift;

Om ze dan vervolgens als gewonen arrays te kunnen gebruiken: @$vendors.

Nadeel van references is wel dat je de waarde van datgene waar je een reference naar hebt ook veranderd wanneer je de reference bewerkt (het is ook niet meer dan een pointer). Stel dus dat je een wijziging in @$vendors doet in Build, dan is @vendors op de plaats waar je $report->Build aanriep ook gewijzigd.

  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 13-09 23:09
Op dinsdag 29 januari 2002 13:51 schreef nonomen het volgende:
Nadeel van references is wel dat je de waarde van datgene waar je een reference naar hebt ook veranderd wanneer je de reference bewerkt (het is ook niet meer dan een pointer). Stel dus dat je een wijziging in @$vendors doet in Build, dan is @vendors op de plaats waar je $report->Build aanriep ook gewijzigd.
Maakt in dit geval niet uit, want die parameters komen van een html-formulier.

SIZE does matter.
"You're go at throttle up!"

Pagina: 1