/ 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
Smide værdier ind i en package
Fra : KB


Dato : 05-11-05 12:53

Hej

Jeg har lavet mig en package med et par subs i.
Når jeg kalder den vil jeg gerne smide nogle variabler ind i den uden at
bruge parameterlisten, f.eks.:

my ($smtp) = new SMTP ();
SMTP->{Server} = "server.host.tld";
SMTP->{Text} = "Text";

Når jeg så kalder
SMTP->Send_Letter ("Email")

skal den kunne anvende den Server-variabel jeg gav den tidligere.

Men hvordan får jeg smidt variablen Server ind i koden, når jeg ikke vil
angive variablerne som et array eller liste i parameterlisten?

/KB



 
 
Michael Zedeler (05-11-2005)
Kommentar
Fra : Michael Zedeler


Dato : 05-11-05 21:35

KB wrote:
> Hej
>
> Jeg har lavet mig en package med et par subs i.
> Når jeg kalder den vil jeg gerne smide nogle variabler ind i den uden at
> bruge parameterlisten, f.eks.:
>
> my ($smtp) = new SMTP ();
> SMTP->{Server} = "server.host.tld";
> SMTP->{Text} = "Text";
>
> Når jeg så kalder
> SMTP->Send_Letter ("Email")
>
> skal den kunne anvende den Server-variabel jeg gav den tidligere.
>
> Men hvordan får jeg smidt variablen Server ind i koden, når jeg ikke vil
> angive variablerne som et array eller liste i parameterlisten?

Du kan lave en pakke-global variabel, som f. eks. $SMTP::Server, men jeg
synes ikke umiddelbart det er specielt pænt ift. det eksempel, du viser
der. Det er mere oplagt at gøre som du allerede gør.

Mvh. Michael.
--
Visit my home page at http://michael.zedeler.dk/
Get my vcard at http://michael.zedeler.dk/vcard.vcf

KB (05-11-2005)
Kommentar
Fra : KB


Dato : 05-11-05 22:38


"Michael Zedeler" <michael@zedeler.dk> wrote in message
news:%H8bf.73415$Fe7.250428@news000.worldonline.dk...

> Det er mere oplagt at gøre som du allerede gør.

Jeg gør nu ikke så meget
Jeg kan nemlig ikke få det til at virke, som jeg gerne vil.

[root@adsl ~]# perl test.pl
Can't use string ("test") as a HASH ref while "strict refs" in use at
test.pm line 9.


Jeg er slet ikke i tvivl om at jeg slet ikke har forstået package systemet
og gør mange mærkelige ting.

/KB




[root@adsl ~]# cat test.pl
#!/usr/bin/perl -w

use strict;
use test;

test->server ("example.com");
test->new ();


[root@adsl ~]# cat test.pm
package test;

use strict;
use warnings;

sub new
{
my $self = shift;
my $server = $self->{server};
print $server ."\n" if defined $server;
}

sub server
{
my ($self, $server) = @_;
}

1;






Michael Zedeler (06-11-2005)
Kommentar
Fra : Michael Zedeler


Dato : 06-11-05 00:39

KB wrote:
> "Michael Zedeler" <michael@zedeler.dk> wrote in message
> news:%H8bf.73415$Fe7.250428@news000.worldonline.dk...
>
>
>>Det er mere oplagt at gøre som du allerede gør.
>
>
> Jeg gør nu ikke så meget
> Jeg kan nemlig ikke få det til at virke, som jeg gerne vil.
>
> [root@adsl ~]# perl test.pl
> Can't use string ("test") as a HASH ref while "strict refs" in use at
> test.pm line 9.
>
>
> Jeg er slet ikke i tvivl om at jeg slet ikke har forstået package systemet
> og gør mange mærkelige ting.

>
> [root@adsl ~]# cat test.pl
> #!/usr/bin/perl -w
>
> use strict;
> use test;
>
> test->server ("example.com");
> test->new ();

Jeg tror dette her er mere oplagt:

my $object = test->new();
$object->server("minlokalemailserver");

Det passer i hvert fald på hvis du vil behandle server som en
instans-metode på klassen test.

> [root@adsl ~]# cat test.pm
> package test;
>
> use strict;
> use warnings;
>
> sub new
> {
> my $self = shift;
> my $server = $self->{server};

De to ovenstående linier er i stykker. Hvad er du ude på at der skal ske?

En slags "generisk" constructor, kan man lave ved at spørge hvad klasse,
variablen skal være sådan her:

my $class = shift;
my $self = <en reference til et eller andet, f. eks. en anonym hashtabel>
....

og endelig

return bless $self, $class;

(Forklæder din reference, så den bliver et rigtigt objekt af typen $class.)

Almindeligvis forklæder man en hashtabel som et objekt, så koden bliver
sådan her:

sub new {
   my $class = shift;
   my $self = {};
   return bless $self, $class;
}

Den returnerer så en reference til en tom hashtabel, som er forklædt som
den klasse, man forventer. Hvis metoden f. eks. er i en pakke, der
hedder "test", kan jeg bare skrive

my $object = test->new();

Hvorefter metoden ovenfor bliver kørt og returnerer et objekt af klassen
"test" til mig.

Jeg tror det er en god idé at tage et kig på nogle manualer. Jeg fandt
en bunke, som er online, her:

http://www.perl.org/books/library.html

Generelt er objekter i perl lidt specielle, fordi den underliggende
struktur er meget synlig. Det kan godt virke forvirrende, hvis man er
vant til Java, hvor det hele sker automagisk.

Mvh. Michael.
--
Visit my home page at http://michael.zedeler.dk/
Get my vcard at http://michael.zedeler.dk/vcard.vcf

KB (06-11-2005)
Kommentar
Fra : KB


Dato : 06-11-05 10:39


"Michael Zedeler" <michael@zedeler.dk> wrote in message
news:bobbf.73427$Fe7.250354@news000.worldonline.dk...

> Jeg tror dette her er mere oplagt:
>
> my $object = test->new();
> $object->server("minlokalemailserver");


Nu gør jeg sådan:

[root@adsl ~]# cat test.pl
#!/usr/bin/perl -w

use strict;
use test;


my $object = test->new();
$object->server("minlokalemailserver");
$object->printer();


[root@adsl ~]# cat test.pm
package test;

use strict;
use warnings;

sub new
{
my $class = shift;
my $self = {};
return bless $self, $class;
}

sub printer
{
my $self = shift;
my $server = $self->{server};
print $server ."\n" if defined $server;
}

sub server
{
my ($self, $server) = @_;
}

1;


Den skriver dog ikke noget, så mit problem lige nu er vel at få refereret
til variablen server i subben server?


> Jeg tror det er en god idé at tage et kig på nogle manualer. Jeg fandt
> en bunke, som er online, her:
>
> http://www.perl.org/books/library.html

Afgjort. Den første ser rigtig pædagogisk ud, men den ser ved hurtig
overskuelse ikke ud til at behandle konceptet packages så meget, men det
finder jeg ud af når jeg får tid til at læse den igennem.

Tak for svarene.

/KB



Soren (News) (06-11-2005)
Kommentar
Fra : Soren (News)


Dato : 06-11-05 11:44

"KB" <kb@kb.kb> writes:

[snip]
> sub server
> {
> my ($self, $server) = @_;
> }

Du bliver nok noedt til at faa den til at goere noget med lokal-variablen $server,
f.eks. $self->{server} = $server;

Mvh,
Soren


KB (06-11-2005)
Kommentar
Fra : KB


Dato : 06-11-05 13:45


"Soren (News)" <sorend@rediffmail.com> wrote in message
news:877jbm83ab.fsf@ser.gratissip.dk...
> "KB" <kb@kb.kb> writes:
>
> [snip]
> > sub server
> > {
> > my ($self, $server) = @_;
> > }
>
> Du bliver nok noedt til at faa den til at goere noget med lokal-variablen
$server,
> f.eks. $self->{server} = $server;


Ahh - Så virker det

Tak for hjælpen til alle.

Er der nogen der kan forklare mig, hvorfor det er skidt at modificere en
pakkes interne variabler?

For mig at se er det lidt voldsomt at oprette metoder til alle de variabler
man har brug for at rette i.

/KB



Hans Jørgen Jakobsen (06-11-2005)
Kommentar
Fra : Hans Jørgen Jakobsen


Dato : 06-11-05 17:00

On Sun, 6 Nov 2005 13:45:18 +0100, KB wrote:
>
> Er der nogen der kan forklare mig, hvorfor det er skidt at modificere en
> pakkes interne variabler?
>
> For mig at se er det lidt voldsomt at oprette metoder til alle de variabler
> man har brug for at rette i.

Ved brug af metoder kan man bedre skjule implementationsdetaljer/ændre implementaion
uden brugere bliver ramt af ændringer.
Og jo det er mange gange ikke arbejdet værd.... Men er du i tvivl om implementeringen
eller kan forudse mulig optimaliseringer så sørg for det kan ændres uden ændring i
pakkeinterface.
/hjj

Soren (News) (07-11-2005)
Kommentar
Fra : Soren (News)


Dato : 07-11-05 09:32

Hans Jørgen Jakobsen <hjj@wheel.dk> writes:

> On Sun, 6 Nov 2005 13:45:18 +0100, KB wrote:
> >
> > Er der nogen der kan forklare mig, hvorfor det er skidt at modificere en
> > pakkes interne variabler?
> >
> > For mig at se er det lidt voldsomt at oprette metoder til alle de variabler
> > man har brug for at rette i.
>
> Ved brug af metoder kan man bedre skjule implementationsdetaljer/ændre implementaion
> uden brugere bliver ramt af ændringer.
> Og jo det er mange gange ikke arbejdet værd.... Men er du i tvivl om implementeringen
> eller kan forudse mulig optimaliseringer så sørg for det kan ændres uden ændring i
> pakkeinterface.

... nok lidt for avanceret endnu (og grimt ioevrigt), men nu er Perl jo et herligt
sprog hvor man kan alt -- du kan med dens autoloader lave saa du kan saette
vaerdier som metodekald, f.eks. (ikke testet kode):

--- test.pm ---

sub new {
return bless {}, $_[0];
}

sub AUTOLOAD {
my ($this, $newvalue) = @_;

# find metodenavnet (lige en hurtig maade, der findes nok mere sikre)
my ($method) = substr($AUTOLOAD, length(ref($this)) + 2);

return undef unless $method;

$this->{$method} = $newvalue if (defined($newvalue));

return $this->{$method};
}

--- test.pl ---

use test;

my $obj = test->new();
$obj->navn("Soren");
printf "navn=%s\n", $obj->navn;

--

Mvh,
Soren

Michael Zedeler (06-11-2005)
Kommentar
Fra : Michael Zedeler


Dato : 06-11-05 20:50

KB wrote:
> Er der nogen der kan forklare mig, hvorfor det er skidt at modificere en
> pakkes interne variabler?
>
> For mig at se er det lidt voldsomt at oprette metoder til alle de variabler
> man har brug for at rette i.

Start med at skrive et længere script i perl uden brug af oo. Så tror
jeg det begynder at dæmre, hvis du vender tilbage til en gennemgang af
hvad man kan med oo-perl.

Mvh. Michael.
--
Visit my home page at http://michael.zedeler.dk/
Get my vcard at http://michael.zedeler.dk/vcard.vcf

Michael Zedeler (06-11-2005)
Kommentar
Fra : Michael Zedeler


Dato : 06-11-05 20:48

KB wrote:
> [klip]
> Nu gør jeg sådan:
>
> [root@adsl ~]# cat test.pl
> #!/usr/bin/perl -w
>
> [klip]
>
> sub new
> {
> my $class = shift;
> my $self = {};
> return bless $self, $class;
> }
>
> sub printer
> {
> my $self = shift;
> my $server = $self->{server};
> print $server ."\n" if defined $server;
> }
>
> sub server
> {
> my ($self, $server) = @_;
> }
>
> Den skriver dog ikke noget, så mit problem lige nu er vel at få refereret
> til variablen server i subben server?

Det er fordi du aldrig stopper noget ned i hashtabellen, som du bruger
som objekt. Nu er det på tide at læse lidt i nogle af de bøger, jeg har
sendt henvisninger til. Du har ikke styr på perl, så start med at kigge
på hvordan det virker uden oo.

Dette kode laver en hashreference og putter noget i den:

$hashref = {};
$hashref->{server} = "kylling.dk";
print $hashref->{server}, "\n";

>>Jeg tror det er en god idé at tage et kig på nogle manualer. Jeg fandt
>>en bunke, som er online, her:
>>
>>http://www.perl.org/books/library.html
>
> Afgjort. Den første ser rigtig pædagogisk ud, men den ser ved hurtig
> overskuelse ikke ud til at behandle konceptet packages så meget, men det
> finder jeg ud af når jeg får tid til at læse den igennem.

God læselyst

Mvh. Michael.
--
Ingen er en alle kender, som ingen har mødt.
Ergo har ingen mødt sig selv.
Visit my home page at http://michael.zedeler.dk/
Get my vcard at http://michael.zedeler.dk/vcard.vcf

Søg
Reklame
Statistik
Spørgsmål : 177564
Tips : 31968
Nyheder : 719565
Indlæg : 6408970
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste