/ Forside / Teknologi / Udvikling / Perl / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Perl
#NavnPoint
bjarneA 141
poul_from 50
soccer 30
Nicknack 14
Tmpj 0
Perl OO - første forsøg
Fra : Martin M. Pedersen


Dato : 13-11-07 14:14

Jeg prøver at lave noget OO i perl for første gang, og har lidt
problemer.
To klasser 'Deck' og 'Card', hvor et 'Deck' skal indeholde nogle
'Card' objekter.

Problem 1:
tusk@skarbinika/programming/perl/modern_art$ ./game.pl
kind:1, artist: G
Can't call method "print" on unblessed reference at Deck.pm line 30.

Problem 2:
Hvordan får jeg korrekt lavet nogle 'Card' objekter og lagt dem ind i
et array i et 'Deck' objekt ?


==Card.pm==
package Card;
use strict;

my $count=0;

#constructor
sub new {
my $class=shift;
my $a=shift;
my $k=shift;
my $self={};

$self->{_artist}=undef; #_L_ite metal, _K_rypto, _Y_oko, karl
_G_litter, _C_hr
istin p
$self->{_kind}=undef; # _1_ once around, _d_ouble auction, _o_pen
auction,
# _f_ixed price, _h_idden auction
if (defined($a)) {
$self->{_artist}=$a;
}
if (defined($k)) {
$self->{_kind}=$k;
}
bless($self,$class);
$count++;

return $self;
}

#destroy
sub DESTROY { --$count }

#accessor method for Card _kind
sub kind {
my $self=shift;
if (@_) { $self->{_kind}=shift }
return $self->{_kind};
}

#accessor method for Card _artist
sub artist {
my $self=shift;
if (@_) { $self->{_artist}=shift }
return $self->{_artist};
}


sub print {
my $self=shift;
printf("kind:%s, artist: %s\n",$self->kind,$self->artist);
}

1;


==Deck.pm==
package Deck;
use strict;

my $count=0;

#constructor
sub new {
my $class=shift;
my $self={};

$self->{_cards}[0]=Card->new('K','f'); #hvorfor virker
push($self->{_cards},Card->new('K','f')); ikke ?
$self->{_cards}[1]=Card->new('Y','d');
$self->{_cards}[2]=Card->new('C','h');
$self->{_cards}[3]=Card->new('G','1');
$self->{_cards}[4]=Card->new('L','o');

$count++;
bless($self,$class);
return $self;
}

#destroy
sub DESTROY { --$count }

# virker ikke
# Can't call method "print" on unblessed reference at Deck.pm line 30.
sub print {
my $self=shift;
foreach my $card ($self->{_cards}) {
$card->print();
}
}

1;

==game.pl==
#!/usr/bin/perl -w
use strict;
use Card;
use Deck;

my $a_card=Card->new('G','1');
$a_card->print();

my $a_deck=Deck->new();
$a_deck->print();






 
 
Peter Makholm (13-11-2007)
Kommentar
Fra : Peter Makholm


Dato : 13-11-07 14:31

"Martin M. Pedersen" <traxplayer@gmail.com> writes:

> Problem 1:
> Problem 2:

Begge dine problemer handler om at du ikke har forstået hvordan du
håndtere en arrayref. Prøv at læse 'perldoc perlreftut' og se om det
ikke hjælper.

> ==Deck.pm==
> package Deck;
> use strict;
>
> my $count=0;
>
> #constructor
> sub new {
> my $class=shift;
> my $self={};

$self er en hashref.

>
> $self->{_cards}[0]=Card->new('K','f'); #hvorfor virker push($self->{_cards},Card->new('K','f')); ikke ?

Da $self->{_cards} er udefineret bliver den her automatisk oprettet
som en arrayref. Bemærk 'The Arrow Rule': In between two subscripts,
the arrow is optional.

Du har et array der hedder '@{ $self->{cards} }'. Det kan du pushe
ting på. Alternativt kan du gøre det mere eksplicit:

$self->{_cards} = [
Card->new('K','f'),
Card->new('Y','d'),
Card->new('C','h'),
Card->new('G','1'),
Card->new('L','o'),
];

Så har du helt eksplicit en arrayref i din kode.

> $self->{_cards}[1]=Card->new('Y','d');
> $self->{_cards}[2]=Card->new('C','h');
> $self->{_cards}[3]=Card->new('G','1');
> $self->{_cards}[4]=Card->new('L','o');
>
> $count++;
> bless($self,$class);
> return $self;
> }
>
> #destroy
> sub DESTROY { --$count }
>
> # virker ikke
> # Can't call method "print" on unblessed reference at Deck.pm line 30.
> sub print {
> my $self=shift;
> foreach my $card ($self->{_cards}) {

'$self->{_cards}' er ikke et array, det er en arrayref. Dit array hedder
'@{ $self->{_cards} }'.

> $card->print();
> }
> }

//Makholm

PS: Nå du angiver en fejlmeddelse der henviser til en linje i din kode er
det en god ide klart at angive hvilke linjer der er tale om.


Martin M. Pedersen (17-11-2007)
Kommentar
Fra : Martin M. Pedersen


Dato : 17-11-07 19:02

Peter Makholm wrote:
> "Martin M. Pedersen" <traxplayer@gmail.com> writes:
>
>> Problem 1:
>> Problem 2:
>
> Begge dine problemer handler om at du ikke har forstået hvordan du
> håndtere en arrayref. Prøv at læse 'perldoc perlreftut' og se om det
> ikke hjælper.

Tak. Det hjælper.

> Du har et array der hedder '@{ $self->{cards} }'. Det kan du pushe
> ting på. Alternativt kan du gøre det mere eksplicit:
>
> $self->{_cards} = [
> Card->new('K','f'),
> Card->new('Y','d'),
> Card->new('C','h'),
> Card->new('G','1'),
> Card->new('L','o'),
> ];

Er det en smart måde at skabe og pushe flere 'Card' objekter med samme
værdier f.x. 7 stk. Card->new('K','f') på samme tid ?

Mvh
Martin

Peter Makholm (17-11-2007)
Kommentar
Fra : Peter Makholm


Dato : 17-11-07 19:18

"Martin M. Pedersen" <traxplayer@gmail.com> writes:

> Er det en smart måde at skabe og pushe flere 'Card' objekter med samme
> værdier f.x. 7 stk. Card->new('K','f') på samme tid ?

Nej, der findes ikke nogen speciel smart perlish måde at gøre det
på hvis der er tale om 7 forskellige objekter med samme værdier. Du
skal gøre det i en løkke, hvor du dog kan bruge en for-modifier:

push @array, Card->new( ... ) for 1 .. 7;

Hvis du vil pushe same objekt flere gange kan du gøre noget ala:

$obj = Card->new( ... );
push @array, $obj for 1 .. 7;

eller måske noget ala:

push @array, ( Card->new( ... ) ) x 7;

se 'perldoc perlop' for x-operatoren. Står under overskriften
'Multiplicative Operators'. Men det vil nok virke lidt som et hack.

//Makholm


Søg
Reklame
Statistik
Spørgsmål : 177414
Tips : 31962
Nyheder : 719565
Indlæg : 6407847
Brugere : 218876

Månedens bedste
Årets bedste
Sidste års bedste