Existenz eines Skalar prüfen

Existenz eines Skalar prüfen

am 01.12.2006 16:19:02 von Frank Seitz

Hallo,

ich möchte wissen, ob ein Paket P eine Paketvariable v definiert.
Für Arrays und Hashes mache ich es folgendermaßen:

$ref = *P::v{ARRAY};
bzw.
$ref = *P::v{HASH};

$ref ist eine Referenz auf die Variable, wenn die betreffende
Paketvariable existiert, sonst undef. *P::v{SCALAR} gibt es
auch, liefert allerdings immer eine Referenz, auch wenn
das Paket die Variable nicht definiert. Das ist auch so dokumentiert.
Meine Frage ist nun: Wie prüfe die Existenz eines Skalar?

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Existenz eines Skalar prüfen

am 01.12.2006 23:59:17 von Slaven Rezic

Frank Seitz writes:

> Hallo,
>
> ich möchte wissen, ob ein Paket P eine Paketvariable v definiert.
> Für Arrays und Hashes mache ich es folgendermaßen:
>
> $ref = *P::v{ARRAY};
> bzw.
> $ref = *P::v{HASH};
>
> $ref ist eine Referenz auf die Variable, wenn die betreffende
> Paketvariable existiert, sonst undef. *P::v{SCALAR} gibt es
> auch, liefert allerdings immer eine Referenz, auch wenn
> das Paket die Variable nicht definiert. Das ist auch so dokumentiert.
> Meine Frage ist nun: Wie prüfe die Existenz eines Skalar?
>

Devel::Symdump scheint keine Antwort auf diese Frage zu haben. Und das
darauf basierende Modul Apache::Status (Bestandteil von mod_perl und
sichtbar, falls nach Default konfiguriert, im Browser unter der URL
http://localhost/perl-status) benutzt einen billigen Trick, um nur
echte Skalare anzuzeigen:

next unless defined eval { $$_ };

Gruß,
Slaven

--
Slaven Rezic - slaven rezic de

Lost in your Tk widget tree? Try
http://user.cs.tu-berlin.de/~eserte/src/perl/Tk-WidgetDump/

Re: Existenz eines Skalar prüfen

am 04.12.2006 08:58:15 von Ferry Bolhar

Frank Seitz:

> $ref ist eine Referenz auf die Variable, wenn die betreffende
> Paketvariable existiert, sonst undef. *P::v{SCALAR} gibt es
> auch, liefert allerdings immer eine Referenz, auch wenn
> das Paket die Variable nicht definiert. Das ist auch so dokumentiert.
> Meine Frage ist nun: Wie prüfe die Existenz eines Skalar?

Was genau willst du wissen?

Wenn ${*P::v{SCALAR}}(d.h, $P::v) definiert ist, wurde der
Skalar eingerichtet, ansonsten nicht oder er wurde als undefiniert
($P::v = undef;) eingerichtet. Eine Möglichkeit, diese beiden Fälle
zu unterscheiden, ist mir nicht bekannt (abgesehen vom Durchsehen
des Sourcecodes von P.pm... ;-).

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: Existenz eines Skalar prüfen

am 04.12.2006 10:39:31 von Mirco Wahab

Frank Seitz wrote:
> Hallo,
>
> ich möchte wissen, ob ein Paket P eine Paketvariable v definiert.
> Für Arrays und Hashes mache ich es folgendermaßen:
>
> $ref = *P::v{ARRAY};
> bzw.
> $ref = *P::v{HASH};
>
> $ref ist eine Referenz auf die Variable, wenn die betreffende
> Paketvariable existiert, sonst undef. *P::v{SCALAR} gibt es
> auch, liefert allerdings immer eine Referenz, auch wenn
> das Paket die Variable nicht definiert. Das ist auch so dokumentiert.
> Meine Frage ist nun: Wie prüfe die Existenz eines Skalar?


Nur über API, etwa so:


package B;
our ($i, $j, $K) = ('Bi', 'Bj', 'BK');

package main;
use Inline C;

var_there('B::j') ? print "OK\n" : print "Nope\n";
var_there('B::k') ? print "OK\n" : print "Nope\n";

__END__
__C__

int var_there(char *name) {
return get_sv(name, FALSE) ? 1 : 0;
}


liefert:

OK
Nope

Re: Existenz eines Skalar prüfen

am 04.12.2006 13:30:01 von Frank Seitz

Slaven Rezic wrote:
> Frank Seitz writes:
>>
>>ich möchte wissen, ob ein Paket P eine Paketvariable v definiert.
>>Für Arrays und Hashes mache ich es folgendermaßen:
>>
>> $ref = *P::v{ARRAY};
>>bzw.
>> $ref = *P::v{HASH};
>>
>>$ref ist eine Referenz auf die Variable, wenn die betreffende
>>Paketvariable existiert, sonst undef. *P::v{SCALAR} gibt es
>>auch, liefert allerdings immer eine Referenz, auch wenn
>>das Paket die Variable nicht definiert. Das ist auch so dokumentiert.
>>Meine Frage ist nun: Wie prüfe die Existenz eines Skalar?
>
> Devel::Symdump scheint keine Antwort auf diese Frage zu haben.

Nein, ich habe in die Sourcen geschaut, Devel::Symdump macht
es genauso wie ich und liefert bei scalars()
erwartungsgemäß u.U. falsche Ergebnisse.

> Und das darauf basierende Modul Apache::Status (Bestandteil
> von mod_perl und sichtbar, falls nach Default konfiguriert, im
> Browser unter der URL http://localhost/perl-status) benutzt einen
> billigen Trick, um nur echte Skalare anzuzeigen:
>
> next unless defined eval { $$_ };

Das ist wohl die bestmögliche Annäherung, wenn es einen
richtigen Test für Skalare wirklich nicht geben sollte -
aber eben nur eine Annäherung.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Existenz eines Skalar prüfen

am 04.12.2006 13:30:38 von Frank Seitz

Ferry Bolhar wrote:
> Frank Seitz:
>>
>>$ref ist eine Referenz auf die Variable, wenn die betreffende
>>Paketvariable existiert, sonst undef. *P::v{SCALAR} gibt es
>>auch, liefert allerdings immer eine Referenz, auch wenn
>>das Paket die Variable nicht definiert. Das ist auch so dokumentiert.
>>Meine Frage ist nun: Wie prüfe die Existenz eines Skalar?
>
> Was genau willst du wissen?
>
> Wenn ${*P::v{SCALAR}}(d.h, $P::v) definiert ist, wurde der
> Skalar eingerichtet, ansonsten nicht oder er wurde als undefiniert
> ($P::v = undef;) eingerichtet.

Eine skalare Variable, die keinen definierten Wert hat
("als undefiniert eingerichtet ist"), existiert,
die möchte die gerne erkennen.

> Eine Möglichkeit, diese beiden Fälle
> zu unterscheiden, ist mir nicht bekannt (abgesehen vom Durchsehen
> des Sourcecodes von P.pm... ;-).

Schade eigentlich.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Existenz eines Skalar prüfen

am 04.12.2006 13:31:11 von Frank Seitz

Mirco Wahab wrote:
> Frank Seitz wrote:
>>
>>ich möchte wissen, ob ein Paket P eine Paketvariable v definiert.
>>Für Arrays und Hashes mache ich es folgendermaßen:
>>
>> $ref = *P::v{ARRAY};
>>bzw.
>> $ref = *P::v{HASH};
>>
>>$ref ist eine Referenz auf die Variable, wenn die betreffende
>>Paketvariable existiert, sonst undef. *P::v{SCALAR} gibt es
>>auch, liefert allerdings immer eine Referenz, auch wenn
>>das Paket die Variable nicht definiert. Das ist auch so dokumentiert.
>>Meine Frage ist nun: Wie prüfe die Existenz eines Skalar?
>
> Nur über API, etwa so:
>
>
> package B;
> our ($i, $j, $K) = ('Bi', 'Bj', 'BK');
>
> package main;
> use Inline C;
>
> var_there('B::j') ? print "OK\n" : print "Nope\n";
> var_there('B::k') ? print "OK\n" : print "Nope\n";
>
> __END__
> __C__
>
> int var_there(char *name) {
> return get_sv(name, FALSE) ? 1 : 0;
> }
>
> liefert:
>
> OK
> Nope

Das funktionuckelt nicht zuverlässig. Gegenbeispiel:

package B;
our @i;

package main;
use Inline 'C';

var_there('B::i') ? print "OK\n" : print "Nope\n";

__END__
__C__

int var_there(char *name) {
return get_sv(name, FALSE) ? 1 : 0;
}

liefert:

OK

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Existenz eines Skalar prüfen

am 04.12.2006 13:48:27 von Robert Sedlacek

Frank Seitz wrote
> Mirco Wahab wrote:
> > Frank Seitz wrote:
> >>
> >>Meine Frage ist nun: Wie prüfe die Existenz eines Skalar?
> >
> > Nur über API, etwa so:
>
> Das funktionuckelt nicht zuverlässig. Gegenbeispiel:
>
> package B;
> our @i;

@i ist auch kein Skalar ;)

gr.,
Robert

--
Hear the chants of old powers, the weak fall on their swords.
Nature is above all morals, destiny a shameless whore.
-- Sol Invictus, Black Easter

Re: Existenz eines Skalar prüfen

am 04.12.2006 13:51:06 von Frank Seitz

Robert 'phaylon' Sedlacek wrote:
> Frank Seitz wrote
>>
>>Das funktionuckelt nicht zuverlässig. Gegenbeispiel:
>>
>>package B;
>>our @i;
>
> @i ist auch kein Skalar ;)

Eben. :)

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Existenz eines Skalar prüfen

am 04.12.2006 14:23:46 von Mirco Wahab

Frank Seitz wrote:
> Robert 'phaylon' Sedlacek wrote:
>> Frank Seitz wrote
>>> Das funktionuckelt nicht zuverlässig. Gegenbeispiel:
>>>
>>> package B;
>>> our @i;
>> @i ist auch kein Skalar ;)
>
> Eben. :)

Dann musst Du die Tippeltappeltour machen:

package B;
our $scalar = 'Bj';
our $wrong = undef;
our @array;
our %hash;

package main;
use Inline C;

true_scalar('B::scalar') ? print "OK\n" : print "Nope\n";
true_scalar('B::wrong') ? print "OK\n" : print "Nope\n";
true_scalar('B::nothere')? print "OK\n" : print "Nope\n";
true_scalar('B::array') ? print "OK\n" : print "Nope\n";
true_scalar('B::hash') ? print "OK\n" : print "Nope\n";

__END__
__C__

int true_scalar(char *name)
{
SV *sv = get_sv(name, FALSE);
if( sv && !get_av(name, FALSE)
&& !get_cv(name, FALSE)
&& !get_hv(name, FALSE) )
return 1;

return 0;
}



Viele Grüße

M.

Re: Existenz eines Skalar prüfen

am 04.12.2006 14:26:14 von Robert Sedlacek

Frank Seitz wrote
> Robert 'phaylon' Sedlacek wrote:
> > Frank Seitz wrote
> >>
> >>Das funktionuckelt nicht zuverlässig. Gegenbeispiel:
> >>
> >>package B;
> >>our @i;
> >
> > @i ist auch kein Skalar ;)
>
> Eben. :)

Wie "eben"? Du fragtest nach einem Test fuer einen Skalar. In dem Sinne
funktioniert das sehr wohl zuverlaessig :)

gr.,
Robert

--
The first rule of project mayhem is: you do not ask questions.
-- Fight Club

Re: Existenz eines Skalar prüfen

am 04.12.2006 14:34:40 von Frank Seitz

Robert 'phaylon' Sedlacek wrote:
> Frank Seitz wrote
>>Robert 'phaylon' Sedlacek wrote:
>>>Frank Seitz wrote
>>>>
>>>>Das funktionuckelt nicht zuverlässig. Gegenbeispiel:
>>>>
>>>>package B;
>>>>our @i;
>>>
>>>@i ist auch kein Skalar ;)
>>
>>Eben. :)
>
> Wie "eben"? Du fragtest nach einem Test fuer einen Skalar. In dem Sinne
> funktioniert das sehr wohl zuverlaessig :)

Wenn im Package kein Skalar vereinbart ist, ich
aber einen gemeldet bekomme, findest Du das zuverlässig?

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Existenz eines Skalar prüfen

am 04.12.2006 14:43:49 von Frank Seitz

Mirco Wahab wrote:

> Dann musst Du die Tippeltappeltour machen:
>
> package B;
> our $scalar = 'Bj';
> our $wrong = undef;
> our @array;
> our %hash;
>
> package main;
> use Inline C;
>
> true_scalar('B::scalar') ? print "OK\n" : print "Nope\n";
> true_scalar('B::wrong') ? print "OK\n" : print "Nope\n";
> true_scalar('B::nothere')? print "OK\n" : print "Nope\n";
> true_scalar('B::array') ? print "OK\n" : print "Nope\n";
> true_scalar('B::hash') ? print "OK\n" : print "Nope\n";
>
> __END__
> __C__
>
> int true_scalar(char *name)
> {
> SV *sv = get_sv(name, FALSE);
> if( sv && !get_av(name, FALSE)
> && !get_cv(name, FALSE)
> && !get_hv(name, FALSE) )
> return 1;
>
> return 0;
> }

Netter Einfall, ist aber auch zu kurz gedacht:

package B;
our @array;
our $array;

package main;
use Inline 'C';

true_scalar('B::array') ? print "OK\n" : print "Nope\n";

__END__
__C__

int true_scalar(char *name)
{
SV *sv = get_sv(name, FALSE);
if( sv && !get_av(name, FALSE)
&& !get_cv(name, FALSE)
&& !get_hv(name, FALSE) )
return 1;

return 0;
}

Liefert: Nope

BTW: Für alles das, was Du da machst, brauchst Du kein C,
weil es dasselbe Verhalten ist wie auf Perl-Ebene.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Existenz eines Skalar prüfen

am 04.12.2006 14:46:06 von Ch Lamprecht

Frank Seitz schrieb:
> Mirco Wahab wrote:
>
>>Frank Seitz wrote:
>>
>>>ich möchte wissen, ob ein Paket P eine Paketvariable v definiert.
>>>Für Arrays und Hashes mache ich es folgendermaßen:
>>>
>>> $ref = *P::v{ARRAY};
>>>bzw.
>>> $ref = *P::v{HASH};
>>>
>>>$ref ist eine Referenz auf die Variable, wenn die betreffende
>>>Paketvariable existiert, sonst undef. *P::v{SCALAR} gibt es
>>>auch, liefert allerdings immer eine Referenz, auch wenn
>>>das Paket die Variable nicht definiert. Das ist auch so dokumentiert.
>>>Meine Frage ist nun: Wie prüfe die Existenz eines Skalar?
>>
>>Nur über API, etwa so:
>>
>>
>> package B;
>> our ($i, $j, $K) = ('Bi', 'Bj', 'BK');
>>
>> package main;
>> use Inline C;
>>
>> var_there('B::j') ? print "OK\n" : print "Nope\n";
>> var_there('B::k') ? print "OK\n" : print "Nope\n";
>>
>> __END__
>> __C__
>>
>> int var_there(char *name) {
>> return get_sv(name, FALSE) ? 1 : 0;
>> }
>>
>>liefert:
>>
>> OK
>> Nope
>
>
> Das funktionuckelt nicht zuverlässig. Gegenbeispiel:
>
> package B;
> our @i;
>
> package main;
> use Inline 'C';
>
> var_there('B::i') ? print "OK\n" : print "Nope\n";
>
> __END__
> __C__
>
> int var_there(char *name) {
> return get_sv(name, FALSE) ? 1 : 0;
> }
>
> liefert:
>
> OK
Es gibt scheinbar keinen GLOB ohne SCALAR - Eintrag.

use warnings;
use Devel::Peek;

#%X::v;
@X::v;
#$X::v ;
#sub X::v;
#sub X::v{};


foreach my $name ( keys %X::) {
my $ref = \ ( $X::{$name} );
print "$name\n";
print ref $ref , "\n";
Dump $ref;
}


Dennoch kann man im output von Devel::Peek::Dump() sehen, ob die Variable einmal
definiert war:

use Devel::Peek;

print "\n\n";
Dump $X::v;

$X::v = 1;

print "\n\n";
Dump $X::v;

$X::v = undef;

print "\n\n";
Dump $X::v;


Gibt aus:

SV = NULL(0x0) at 0x18317b0
REFCNT = 1
FLAGS = ()


SV = IV(0x1826e68) at 0x18317b0
REFCNT = 1
FLAGS = (IOK,pIOK)
IV = 1


SV = IV(0x1826e68) at 0x18317b0
REFCNT = 1
FLAGS = ()
IV = 1

Allein was hilft es ;)
Christoph

Re: Existenz eines Skalar prüfen

am 04.12.2006 14:46:18 von Robert Sedlacek

Frank Seitz wrote
> Wenn im Package kein Skalar vereinbart ist, ich
> aber einen gemeldet bekomme, findest Du das zuverlässig?

Ah, jetzt hab' ich's verstanden. Sorry, mein Fehler :)

--
Ordinary morality is only for ordinary people.
-- Aleister Crowley

Re: Existenz eines Skalar prüfen

am 04.12.2006 14:54:07 von Daniel Fischer

Frank Seitz!

> Netter Einfall, ist aber auch zu kurz gedacht:

Ich will auch mal:

sub var_there($) {
my @var = split /::/, $_[0];
unshift @var, 'main' unless @var > 1;
my $var = pop @var;
my $pkg = join '::', @var;
open my $olderr, '>&', \*STDERR;
close STDERR;
my $err = '';
open STDERR, '>', \$err;
eval "{use strict; package $pkg; \$$var}";
my $err = $err || $@;
close STDERR;
open STDERR, '>&', $olderr;
! $err;
}

Ich weiß schon, dass es für mindestens zwei Skalare ein false positive
liefert, aber wie man das jetzt noch zuverlässig weg kriegt - keine
Ahnung.


Gruß
Daniel

Re: Existenz eines Skalar prüfen

am 04.12.2006 14:54:40 von Christian Winter

Mirco Wahab schrieb:
> Frank Seitz wrote:
>> Robert 'phaylon' Sedlacek wrote:
>>> Frank Seitz wrote
>>>> Das funktionuckelt nicht zuverlässig. Gegenbeispiel:
>>>>
>>>> package B;
>>>> our @i;
>>> @i ist auch kein Skalar ;)
>>
>> Eben. :)
>
> Dann musst Du die Tippeltappeltour machen:
>
[...snipped...]
> int true_scalar(char *name)
> {
> SV *sv = get_sv(name, FALSE);
> if( sv && !get_av(name, FALSE)
> && !get_cv(name, FALSE)
> && !get_hv(name, FALSE) )
> return 1;
>
> return 0;
> }

Das gibt auch falsche Resultate, wenn ein Name mehrfach belegt
ist, z.B.
our( $i, @i ) = ('lala', 'lolo', 'lili');
Hier sind sowohl get_sv als auch get_av wahr. Mit SvOK lässt sich
aber testen, ob ein SV einen gültigen (definierten) Skalar darstellt.

int true_scalar(char *name)
{
SV *sv = get_sv(name, FALSE);
if( sv && SvOK(sv) )
return 1;

return 0;
}

-Christian

Re: Existenz eines Skalar prüfen

am 04.12.2006 14:55:50 von Daniel Fischer

Christian Winter!

> Hier sind sowohl get_sv als auch get_av wahr. Mit SvOK lässt sich
> aber testen, ob ein SV einen gültigen (definierten) Skalar darstellt.

Damit wären dann wohl wieder die auf undef initialisierten Skalare raus?


Gruß
Daniel

Re: Existenz eines Skalar prüfen

am 04.12.2006 15:28:05 von Christian Winter

Daniel Fischer schrieb:
> Christian Winter!
>
>> Hier sind sowohl get_sv als auch get_av wahr. Mit SvOK lässt sich
>> aber testen, ob ein SV einen gültigen (definierten) Skalar darstellt.
>
> Damit wären dann wohl wieder die auf undef initialisierten Skalare raus?

Ja. Undefinierte Skalare sind nicht initialisiert. In der Symbol-
tabelle liegt lediglich ein Typeglob mit einen Pointer auf einen
Null-SV, aber der liegt auch drin, wenn ein anderer Typ deklariert
wurde. Also gibt es kein Kriterium, das schlüssig zeigt, ob ein
Skalar dieses Namens in einem Paket enthalten ist, solange er keinen
Wert zugewiesen bekommt.

-Christian

Re: Existenz eines Skalar prüfen

am 04.12.2006 16:02:17 von Ferry Bolhar

Mirco Wahab:

> int var_there(char *name) {
> return get_sv(name, FALSE) ? 1 : 0;

Das funktioniert nur dann, wenn es überhaupt noch keine
Variable mit dem angegebenen Namen (dh., keinen solchen
Typeglob) gibt. Gibt es z.B. ein gleichnamiges Array, Hash
Funktion oder Handle, haut das nicht mehr hin.

Wie Frank schon geschrieben hat, ist der Skalar-Slot eines
Typeglobs _immer_ belegt, auch wenn es keinen Skalarwert
gibt - der Sloteintrag _zeigt_ dann auf den Wert 'undef', _ist_
aber (im Gegensatz zu allen anderen Slots) nicht 'undef'. Es ist
derselbe Zustand, wie wenn man

$B::k = undef; bzw.
*B::k = \undef;

schreibt.

Ich weiß nicht, warum das so ist - wahrscheinlich aus
Gründen der Implementierung - aber es ist dokumentiert
und man muss damit leben. XS-Code kann da leider nichts
daran ändern - sobald der Compiler für irgendeine Variable,
Funktion oder Handle ein Typeglob anlegt, enthält sein
Skalar-Slot eine Referenz auf "undef", die sich durch nichts
von einem zugewiesenen "undef"-Wert unterscheidet. Von
Perl aus nicht und von XS-Code aus auch nicht.

Außer den Source Code selber durchzusehen oder zu
parsen (vielleicht gibt es Module, die eine Art Cross-Listing
- wo wird was definiert, wo wird es verwendet - erstellen
können), sehe ich keine Möglichkeit, Franks Problem zu
lösen.

Seht ihr, nicht nur ich will unerreichbare Dinge (vgl. meinen
Wunsch bzgl. erweitertem Prototyping! ;-)))

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: Existenz eines Skalar prüfen

am 04.12.2006 16:02:18 von Mirco Wahab

Christian Winter wrote:
> Ja. Undefinierte Skalare sind nicht initialisiert. In der Symbol-
> tabelle liegt lediglich ein Typeglob mit einen Pointer auf einen
> Null-SV, aber der liegt auch drin, wenn ein anderer Typ deklariert
> wurde. Also gibt es kein Kriterium, das schlüssig zeigt, ob ein
> Skalar dieses Namens in einem Paket enthalten ist, solange er keinen
> Wert zugewiesen bekommt.

Stimmt genau. Kann man für den Hausgebrauch schonsehen:

package B;
our $k;
our @k;

package main;
use Inline C;
print_namespace("B");

__END__
__C__

int print_namespace(char *name)
{
HV *hv = gv_stashpv(name, FALSE);
I32 kl, i32 = hv_iterinit(hv);
SV *sv;
char *pn;

while( (sv=hv_iternextsv(hv, &pn, &kl )) != 0)
printf("%s\n", pn );

return 0;
}



Viele Grüße

M.

Re: Existenz eines Skalar prüfen

am 04.12.2006 19:50:54 von Frank Seitz

Ferry Bolhar wrote:

[Zu jedem Typeglob wird eine skalare Variable erzeugt,
ob das Paket eine vereinbart oder nicht]

> Seht ihr, nicht nur ich will unerreichbare Dinge (vgl. meinen
> Wunsch bzgl. erweitertem Prototyping! ;-)))

Den Seitenhieb konntest Du Dir natürlich nicht verkneifen :)

Ich kannte das von Dir beschriebene, kurios erscheinende
interne Verhalten nicht, hatte mich nur gewundert, dass
*P::v{SCALAR} immer eine Referenz liefert. Ich buche das
mal unter den Mysterien von Perl ab.

Die Stelle, an der dies dokumentiert ist, klingt so, als ob
das nicht wirklich so sein muss und die Perl-Entwickler
damit auch nicht ganz zufrieden sind:

| *foo{THING} returns undef if that particular THING hasn't
| been used yet, except in the case of scalars. *foo{SCALAR}
| returns a reference to an anonymous scalar if $foo hasn't
| been used yet. This might change in a future release.

Ein deutlich besserer Test als ein simples

!defined ${"$pkg\::$name"}

müsste folgendermaßen möglich sein:

1) Gibt es keinen Symboltablelleneintrag für
den Variablennamen, existiert die skalare Paketvariable nicht.

2) Trifft 1) nicht zu und verweist der Glob-Eintrag für
den Skalar auf eine Variable, deren Wert nicht undef ist,
existiert die skalare Paketvariable.

3) Trifft 1) und 2) nicht zu und sind alle anderen
Glob-Einträge nicht definiert, existiert die skalare
Paketvariable.

4) Treffen 1) und 2) und 3) nicht zu, dann lässt die
Existenz sich nicht sicher entscheiden: Entweder
die Variable existiert wirklich nicht oder sie hat den Wert
undef UND es existiert eine zweiter Globeintrag
für denselben Namen (z.B. für ein Array oder Hash).

Die Mühe für so einen Test scheint sich aber kaum jemand
zu machen, nichtmal der Autor von Devel::Symdump.
Das Modul liefert teilweise gravierend falsche
Ausküfte über Skalare.

Danke an alle, die sich beteiligt haben!

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Existenz eines Skalar prüfen

am 04.12.2006 20:17:15 von Ch Lamprecht

Frank Seitz schrieb:

> | *foo{THING} returns undef if that particular THING hasn't
> | been used yet, except in the case of scalars. *foo{SCALAR}
> | returns a reference to an anonymous scalar if $foo hasn't
> | been used yet. This might change in a future release.
>
> Ein deutlich besserer Test als ein simples
>
> !defined ${"$pkg\::$name"}
>
> müsste folgendermaßen möglich sein:
>
> 1) Gibt es keinen Symboltablelleneintrag für
> den Variablennamen, existiert die skalare Paketvariable nicht.
>
> 2) Trifft 1) nicht zu und verweist der Glob-Eintrag für
> den Skalar auf eine Variable, deren Wert nicht undef ist,
> existiert die skalare Paketvariable.


Es gibt noch den Fall, dass 1) nicht zutrifft, aber der Symboltabelleneintrag
gar kein GLOB ist, sondern ein SCALAR mit Wert -1. Dann ist eine Funktion des
Namens im Paket declared aber nicht definiert (und natürlich existiert keine
Variable des Namens).

Christoph
>
> 3) Trifft 1) und 2) nicht zu und sind alle anderen
> Glob-Einträge nicht definiert, existiert die skalare
> Paketvariable.
>
> 4) Treffen 1) und 2) und 3) nicht zu, dann lässt die
> Existenz sich nicht sicher entscheiden: Entweder
> die Variable existiert wirklich nicht oder sie hat den Wert
> undef UND es existiert eine zweiter Globeintrag
> für denselben Namen (z.B. für ein Array oder Hash).
>
> Die Mühe für so einen Test scheint sich aber kaum jemand
> zu machen, nichtmal der Autor von Devel::Symdump.
> Das Modul liefert teilweise gravierend falsche
> Ausküfte über Skalare.
>
> Danke an alle, die sich beteiligt haben!
>
> Grüße
> Frank


--

perl -e "print scalar reverse q/ed.enilno@ergn.l.hc/"

Re: Existenz eines Skalar prüfen

am 05.12.2006 07:32:30 von Daniel Fischer

Frank Seitz!

> 4) Treffen 1) und 2) und 3) nicht zu, dann lässt die
> Existenz sich nicht sicher entscheiden

Hier könnte man das, was ich woanders im Thread gepostet habe, als Keule
rausholen. Ich verwende eval und use strict um den Compile-Zeit-Fehler
abzufangen, der beim Zugriff auf eine nicht existierende Variable
auftritt. Das gibt kein false positive für Arrays und Hashes. Wohl aber
für $a und $b. Frag nicht. Das ist Perl!


Gruß
Daniel

Re: Existenz eines Skalar prüfen

am 05.12.2006 10:09:34 von Frank Seitz

Daniel Fischer wrote:
> Frank Seitz!
>>
>>4) Treffen 1) und 2) und 3) nicht zu, dann lässt die
>>Existenz sich nicht sicher entscheiden
>
> Hier könnte man das, was ich woanders im Thread gepostet habe, als Keule
> rausholen. Ich verwende eval und use strict um den Compile-Zeit-Fehler
> abzufangen, der beim Zugriff auf eine nicht existierende Variable
> auftritt.

Interessante Idee. Ich frage mich, wie Perl selbst
entscheidet, ob eine skalare Variable existiert.

> Das gibt kein false positive für Arrays und Hashes. Wohl aber
> für $a und $b. Frag nicht. Das ist Perl!

Das kann ich erklären: $a und $b sind zwei vordefinierte
Variable, die Perl im Zusammenhang mit sort() benutzt.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Existenz eines Skalar prüfen

am 05.12.2006 10:13:26 von Daniel Fischer

Frank Seitz!

> Interessante Idee. Ich frage mich, wie Perl selbst entscheidet, ob eine
> skalare Variable existiert.

Zur Compilezeit weiß perl das eben noch. Nur zur Laufzeit vergisst es
das. Deshalb funktioniert ja mein eval-Konstrukt, weil das den Fehler zur
Compilezeit auslöst, wenn die Variable nicht existiert.

> Das kann ich erklären: $a und $b sind zwei vordefinierte Variable, die
> Perl im Zusammenhang mit sort() benutzt.

Jo, ich weiß, das steht so in perldoc strict (oder irgendwo anders stand
es, aber ich glaube, dort).


Gruß
Daniel

Re: Existenz eines Skalar prüfen

am 05.12.2006 11:27:37 von Frank Seitz

Daniel Fischer wrote:
> Frank Seitz!
>>
>>Interessante Idee. Ich frage mich, wie Perl selbst entscheidet, ob eine
>>skalare Variable existiert.
>
> Zur Compilezeit weiß perl das eben noch. Nur zur Laufzeit vergisst es
> das. Deshalb funktioniert ja mein eval-Konstrukt, weil das den Fehler zur
> Compilezeit auslöst, wenn die Variable nicht existiert.

Wenn ich es richtig gesehen habe, benutzt Du eval "..." (String,
kein Block). Das wird zur Laufzeit ausgeführt.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Existenz eines Skalar prüfen

am 05.12.2006 11:30:40 von Frank Seitz

Daniel Fischer wrote:
> Frank Seitz!
>>
>>Interessante Idee. Ich frage mich, wie Perl selbst entscheidet, ob eine
>>skalare Variable existiert.
>
> Zur Compilezeit weiß perl das eben noch. Nur zur Laufzeit vergisst es
> das. Deshalb funktioniert ja mein eval-Konstrukt, weil das den Fehler zur
> Compilezeit auslöst, wenn die Variable nicht existiert.

Wenn ich es richtig gesehen habe, benutzt Du eval "..." (String,
kein Block). Der Code wird zur Laufzeit interpretiert.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Existenz eines Skalar prüfen

am 05.12.2006 11:49:36 von Daniel Fischer

Frank Seitz!

> Wenn ich es richtig gesehen habe, benutzt Du eval "..." (String, kein
> Block). Der Code wird zur Laufzeit interpretiert.

Geparst und übersetzt wird's trotzdem vorher, aber eben (im Unterschied
zur Block-Syntax) dann, wenn eval aufgerufen wird. Deshalb können
Compilezeit-Fehler abgefangen werden.

Bei der Block-Syntax wird der eval-Block zusammen mit dem umgebenden
Programm geparst und übersetzt, deshalb geht das damit nicht.


Gruß
Daniel

Re: Existenz eines Skalar prüfen

am 05.12.2006 12:12:12 von Ferry Bolhar

Frank Seitz:

> Die Stelle, an der dies dokumentiert ist, klingt so, als ob
> das nicht wirklich so sein muss und die Perl-Entwickler
> damit auch nicht ganz zufrieden sind:

Ich vermute, das (und anderes) ist der Grund für die Entwicklung
von Perl6...

> 1) Gibt es keinen Symboltablelleneintrag für
> den Variablennamen, existiert die skalare Paketvariable nicht.

Das muss nicht sein - es kann (theoretisch) ein Typeglob und
damit eine Paketvariable auch ohne Symboltabelleneintrag
existieren (anonymer Typeglob). Ich gebe zu, dass das ziemlich
exotisch ist - aber es ist immerhin möglich. Es kann übrigens
auch Einträge in einer Symboltabelle geben, die keine Typeglobs
(SVGV's) enthalten. Daher kannst du von der Existenz des einen
noch nicht 100%-ig auf die Existenz des anderen schließen.

> 2) Trifft 1) nicht zu und verweist der Glob-Eintrag für
> den Skalar auf eine Variable, deren Wert nicht undef ist,
> existiert die skalare Paketvariable.
>
> 3) Trifft 1) und 2) nicht zu und sind alle anderen
> Glob-Einträge nicht definiert, existiert die skalare
> Paketvariable.

Jein. Es gibt dann einen SV-Eintrag, der "undef" enthält. Die
Variable muss deswegen nicht existieren oder anders gesagt: der
Skalareintrag muss deswegen im Code nicht referenziert worden
sein. Er kann, aber er muss nicht (dir ging es ja um die "Verwendung"
von Paketvariablen).

> 4) Treffen 1) und 2) und 3) nicht zu,

Einer der drei obigen Punkte trifft _immer_ zu. Wenn es einen
Symboltabelleneintrag gibt (und dieser einen Typeglob enthält),
so ist der Skalarwert _immer_ belegt, entweder "undef" oder ein
anderer skalarer Wert. Du kannst aufgrund der Tatsache, dass
andere Einträge belegt sind, nicht daraus schließen, dass der Skalar-
Eintrag nicht verwendet wird - es könnte ja zwei Variablen @hugo
und $hugo gleichzeitig geben.

> Danke an alle, die sich beteiligt haben!

Es gibt übrigens eine Möglichkeit: den Referenzcount des Typeglobs.
Der wird von Compiler jedesmal um eins erhöht, wenn der Glob-
name im Programm verwendet wird. D.h.:

@hugo = (1,2,3);

Referenzcount ist 2 (mit 1 wird der Typeglob angelegt).

Steht jetzt irgendwo anders

print $hugo;

ist der Referenzcount 3.

Du must also nur den Referenzcount des Typeglobs ermitteln
und dann für jedes

@hugo;
%hugo;
&hugo (oder hugo())
*hugo
hugo (File- bzw. Formathandle)

im Code eins abziehen. Bleibt dir zum Schluss ein Wert größer
eins übrig, wurde auch irgendwo im Code $hugo verwendet ;-)

> Die Mühe für so einen Test scheint sich aber kaum jemand
> zu machen, nichtmal der Autor von Devel::Symdump.

Vielleicht verstehst du jetzt, warum... ;-))

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: Existenz eines Skalar prüfen

am 05.12.2006 12:13:00 von Ferry Bolhar

Daniel Fischer:

> Hier könnte man das, was ich woanders im Thread gepostet habe, als Keule
> rausholen. Ich verwende eval und use strict um den Compile-Zeit-Fehler
> abzufangen, der beim Zugriff auf eine nicht existierende Variable
> auftritt.

Was genau machst du da?

> Das gibt kein false positive für Arrays und Hashes.

"False positive"?

> Wohl aber für $a und $b. Frag nicht. Das ist Perl!

$a und $b (die innerhalb von sort()-Blocks verwendet werden),
haben während des Compilierens einen Sonderstatus - sie sind
von "use strict" ausgenommen. Der Parser prüft ganz einfach nach,
ob der Name eines Skalars mit 'a' oder 'b' beginnt und genau ein
Zeichen lang ist. Ist das so, gilt er als importiert und daher regt
sich "use strict" nicht auf.

Ich kenne deinen "Abfang-Code" nicht, vermute aber, dass
dessen Verhalten mit dem Sonderstatus von $a und $b zu tun
hat.

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: Existenz eines Skalar prüfen

am 05.12.2006 12:41:39 von Frank Seitz

Daniel Fischer wrote:
> Frank Seitz!
>>
>>Wenn ich es richtig gesehen habe, benutzt Du eval "..." (String, kein
>>Block). Der Code wird zur Laufzeit interpretiert.
>
> Geparst und übersetzt wird's trotzdem vorher,

Aber nicht zur Compilezeit des eigentlichen Programms,
das die Variable, die geprüft wird, einführt.
Also kann Perl selbst die Existenz einer Skalaren
Variable zu einem späteren Zeitpunkt durchaus
sicher feststellen.

> aber eben (im Unterschied
> zur Block-Syntax) dann, wenn eval aufgerufen wird. Deshalb können
> Compilezeit-Fehler abgefangen werden.
>
> Bei der Block-Syntax wird der eval-Block zusammen mit dem umgebenden
> Programm geparst und übersetzt, deshalb geht das damit nicht.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Existenz eines Skalar prüfen

am 05.12.2006 12:43:24 von Ferry Bolhar

Frank Seitz:

> Interessante Idee. Ich frage mich, wie Perl selbst
> entscheidet, ob eine skalare Variable existiert.

In letzter Konsequenz gar nicht. Ansonsten:

anhand des Referenzzählers des jeweiligen Typeglobs (SVGV).
Außerdem gibt es im Typeglob ein Flag (Gvf_MULTI), welches,
wenn es gesetzt ist, "used only once" Meldungen unterdrückt. Das
ist zB. bei $a und $b, aber auch %ENV, @INC usw. gesetzt.

Dieser Test hat allerdings einen Pferdefuß - es wird nur getestet,
ob ein _Name_ mehr als einmal verwendet wird. Wenn also im
Programm jeweils

$hugo
@hugo

nur einmal verwendet wird, ist der Referenzzähler von *hugo
auf 2 und für Perl ist die Welt wieder in Ordnung. Und da sich
das MULTI-Flag im Typeglob befindet, wird Perl auch nie
darüber jammern, wenn z.B.

$INC

so es verwendet wird, nur einmal im Code vorkommt. Also ist
auch das genaugenommen nur eine halbe Sache.

Die Frage nach der Existenz einer skalaren Variable stellt sich
nicht - jeder bisher nicht referenzierte Skalar ist "undef" (dies
könnte ein Grund sein, warum der Skalareintrag eines Typeglobs
von vorneherein mit einer Referenz auf diesen Wert angelegt wird).
Perl muss weder beim Compilieren noch zur Laufzeit wissen, ob
eine skalare Variable bereits referenziert wurde oder nicht und
daher gibt es auch keinen expliziten Test dafür.

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: Existenz eines Skalar prüfen

am 05.12.2006 12:56:05 von Frank Seitz

Ferry Bolhar wrote:
> Frank Seitz:
>>
>>Interessante Idee. Ich frage mich, wie Perl selbst
>>entscheidet, ob eine skalare Variable existiert.
>
> In letzter Konsequenz gar nicht. Ansonsten:
>
> anhand des Referenzzählers des jeweiligen Typeglobs (SVGV).
> Außerdem gibt es im Typeglob ein Flag (Gvf_MULTI), welches,
> wenn es gesetzt ist, "used only once" Meldungen unterdrückt. Das
> ist zB. bei $a und $b, aber auch %ENV, @INC usw. gesetzt.
>
> Dieser Test hat allerdings einen Pferdefuß - es wird nur getestet,
> ob ein _Name_ mehr als einmal verwendet wird. Wenn also im
> Programm jeweils
>
> $hugo
> @hugo
>
> nur einmal verwendet wird, ist der Referenzzähler von *hugo
> auf 2 und für Perl ist die Welt wieder in Ordnung. Und da sich
> das MULTI-Flag im Typeglob befindet, wird Perl auch nie
> darüber jammern, wenn z.B.
>
> $INC
>
> so es verwendet wird, nur einmal im Code vorkommt. Also ist
> auch das genaugenommen nur eine halbe Sache.

Der Referenzähler des Typeglob sagt IMO garnichts über die
Existenz des betreffenden Skalar aus.

> Die Frage nach der Existenz einer skalaren Variable stellt sich
> nicht

Auf Anwendungsebene ist das durchaus interessant.
Auch unter "use strict" wird genau das geprüft.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Existenz eines Skalar prüfen

am 05.12.2006 13:14:12 von Frank Seitz

Ferry Bolhar wrote:
> Frank Seitz:
>>
>>4) Treffen 1) und 2) und 3) nicht zu,
>
> Einer der drei obigen Punkte trifft _immer_ zu.

Nein, denn ich spreche von der logischen Ebene,
nicht von der Implementierungsebene.

> Wenn es einen
> Symboltabelleneintrag gibt (und dieser einen Typeglob enthält),
> so ist der Skalarwert _immer_ belegt, entweder "undef" oder ein
> anderer skalarer Wert.

Löse Dich doch mal von der Implementierung, Ferry. Dass
die in in diesem Zusammenhang etwas vorgaukelt, was
unter Umständen garnicht da ist, ist doch genau das Problem!

>>Die Mühe für so einen Test scheint sich aber kaum jemand
>>zu machen, nichtmal der Autor von Devel::Symdump.
>
> Vielleicht verstehst du jetzt, warum... ;-))

Nein, eigentlich nicht. Wenn der Test gebraucht wird,
muss man ihn irgendwie implementieren. Oder man lässt es
und stellt die damit zusammenhängende Funktionalität
nicht bereit. Oder man weist unter BUGS auf die
entsprechenden Defizite hin.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Existenz eines Skalar prüfen

am 05.12.2006 16:34:47 von Ferry Bolhar

Frank Seitz:

> Der Referenzähler des Typeglob sagt IMO garnichts über die
> Existenz des betreffenden Skalar aus.

Der Referenzzähler eines Typeglobs wird jedesmal inkrementiert,
wenn irgendein "Dings" mit diesem Namen im Code referenziert
wird. Wenn du also einen Typeglob *hugo mit dem Zähler 4 hast,
weißt du, dass "hugo" viermal im Code referenziert wurde.

Wenn du nun noch weißt bzw. feststellst (und das geht ja), dass
kein Array, Hash, Code oder Handle mit diesem Namen ange-
sprochen wurde (weil die entsprechenden Typeglob-Einträge
unbenutzt sind), ist klar, dass nur entweder das Ansprechen des
Typeglobs selber oder des Skalars $hugo zu diesem Zählerwert
geführt haben.

Der Zähler sagt also nicht "gar nichts" aus, aber leider auch nichts
allzu Genaues.

>> Die Frage nach der Existenz einer skalaren Variable stellt sich
>> nicht
>
> Auf Anwendungsebene ist das durchaus interessant.

Warum?

> Auch unter "use strict" wird genau das geprüft.

"use strict vars" (das meinst du eigentlich) sagt dem Compiler,
dass er schreien soll, wenn er auf einen Bezeichner stößt, für
den es entweder noch keinen Typeglob gibt oder für den der
jeweilige Werttyp noch nicht als exportiert gekennzeichnet
wurde.

ZB:

use vars $hugo; (im Package main):

macht ein

*{"main::hugo"} = \${"main::hugo"};

Dadurch wird der Typeglob *main::hugo eingerichtet und
gleichzeitig wird das GVf_SVIMPORTED Flag im Typeglob
gesetzt. Beim nächsten Auffinden von $hugo wird der Compiler
den Typeglob und das Flag darin gesetzt finden und nicht mehr
jammern.

Das nützt dir für dein Problem nur nichts, weil ja nicht
notwendigerweise jede Paketvariable exportiert wird und
daher das Flag gesetzt hat.

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: Existenz eines Skalar prüfen

am 05.12.2006 16:42:40 von Ferry Bolhar

Frank Seitz:

> Löse Dich doch mal von der Implementierung, Ferry. Dass
> die in in diesem Zusammenhang etwas vorgaukelt, was
> unter Umständen garnicht da ist, ist doch genau das Problem!

Wenn ich mich von der Implementierung lösen soll, könnte
ich genauso gut fragen, ob die Implementierung von Paket-
variablen durch Stashes und Typeglobs wirklich die beste
Lösung war (ich denke nicht, und soviel ich weiß, gibt es in
Perl 6 auch keine Typeglobs mehr). Also worüber wollen
wir dann reden?

Du suchst eine Lösung für ein Problem, das _jetzt_ existiert.
Diese Lösung, falls es überhaupt eine gibt, kann also nur
innerhalb bestehender Implementierungs-Vorgaben entwickelt
werden. Daher sehe ich keinen Sinn darin, mich, wie du sagst,
"von der Implementierung zu lösen", außer vielleicht, um über
Lösungsansätze in künftigen Perl-Implementierungen nachzu-
denken. Aber da kann ich dann auch gleich davon ausgehen,
dass es keine Typeglobs mehr gibt und dass Variablen auf
eine ganz andere Art implementiert sein werden.

> Nein, eigentlich nicht. Wenn der Test gebraucht wird,
> muss man ihn irgendwie implementieren.

Klar, bloß scheint er - da immer noch nicht implementiert -
bisher nicht allzu dringend gebraucht worden zu sein.

> Oder man lässt es
> und stellt die damit zusammenhängende Funktionalität
> nicht bereit. Oder man weist unter BUGS auf die
> entsprechenden Defizite hin.

Genau. Wie ich es mit meinen erweiterten Prototypen getan
habe...

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: Existenz eines Skalar prüfen

am 05.12.2006 17:43:26 von Frank Seitz

Ferry Bolhar wrote:
>
> Du suchst eine Lösung für ein Problem, das _jetzt_ existiert.
> Diese Lösung, falls es überhaupt eine gibt, kann also nur
> innerhalb bestehender Implementierungs-Vorgaben entwickelt
> werden.

Folgender Code scheint das Gewünschte zu leisten
(implementiert nach der Idee von Daniel Fischer):

#----------------------------------------------------------- ----------

#!/usr/local/bin/perl -w

use strict;

package P;

our $x;
our $y;
our @y;
our @z;
our %z;

package main;

=head2 getPkgVar - Liefere Referenz auf Paketvariable

$ref = getPkgVar($pkg,$sym,$type);

Liefere eine Referenz auf die Variable mit dem Bezeichner $sym vom
Typ $type ('SCALAR','ARRAY' oder 'HASH') im Paket $pkg. Existiert die
Variable nicht, liefere undef.

=cut

sub getPkgVar
{
my ($pkg,$sym,$type) = @_;

if ($type eq 'SCALAR')
{
use strict;
# Unterdrücke 'Variable "..." is not imported' Warnungen,
# die neben der Exception generiert werden.
local $SIG{__WARN__} = sub {};
eval "package $pkg; \$$sym";
return undef if $@;
}
no strict 'refs';
return *{"$pkg\::$sym"}{$type};
}

for my $type (qw/SCALAR ARRAY HASH/)
{
print "$type:";
for my $sym (qw/x y z/)
{
print " $sym" if getPkgVar('P',$sym,$type);
}
print "\n";
}
__END__
SCALAR: x y
ARRAY: y z
HASH: z

#----------------------------------------------------------- ----------

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Existenz eines Skalar prüfen

am 05.12.2006 18:37:35 von Daniel Fischer

Frank Seitz!

> Folgender Code scheint das Gewünschte zu leisten
> (implementiert nach der Idee von Daniel Fischer):



Aber deins ist huebscher.


Gruß
Daniel

Re: Existenz eines Skalar prüfen

am 05.12.2006 22:48:18 von Slaven Rezic

Frank Seitz writes:

[...]
> >>Die Mühe für so einen Test scheint sich aber kaum jemand
> >>zu machen, nichtmal der Autor von Devel::Symdump.
> >
> > Vielleicht verstehst du jetzt, warum... ;-))
>
> Nein, eigentlich nicht. Wenn der Test gebraucht wird,
> muss man ihn irgendwie implementieren. Oder man lässt es
> und stellt die damit zusammenhängende Funktionalität
> nicht bereit. Oder man weist unter BUGS auf die
> entsprechenden Defizite hin.
>

Wo ist der Bug? "Devel::Symdump - dump symbol names or the symbol
table"

Dass die Befragung der Symboltabelle nicht die Frage nach der Existenz
eines Skalars lösen kann, ist eine andere Geschichte.

Gruß,
Slaven

--
Slaven Rezic - slaven rezic de

need xpm or ppm output from GD?
http://search.cpan.org/search?mode=module&query=GD::Convert

Re: Existenz eines Skalar prüfen

am 06.12.2006 09:28:07 von Frank Seitz

Slaven Rezic wrote:
> Frank Seitz writes:

>>>>Die Mühe für so einen Test scheint sich aber kaum jemand
>>>>zu machen, nichtmal der Autor von Devel::Symdump.
>>>
>>>Vielleicht verstehst du jetzt, warum... ;-))
>>
>>Nein, eigentlich nicht. Wenn der Test gebraucht wird,
>>muss man ihn irgendwie implementieren. Oder man lässt es
>>und stellt die damit zusammenhängende Funktionalität
>>nicht bereit. Oder man weist unter BUGS auf die
>>entsprechenden Defizite hin.
>
> Wo ist der Bug? "Devel::Symdump - dump symbol names or the symbol
> table"

#!/usr/local/bin/perl -w

use strict;
use Devel::Symdump;

package P;

our ($x,@y,%z);

package main;

my $stash = Devel::Symdump->new('P');
for my $scalar ($stash->scalars)
{
print $scalar,"\n";
}
__END__
P::y
P::x
P::z

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Existenz eines Skalar prüfen

am 06.12.2006 11:19:01 von Slaven Rezic

Frank Seitz writes:

> Slaven Rezic wrote:
> > Frank Seitz writes:
>
> >>>>Die Mühe für so einen Test scheint sich aber kaum jemand
> >>>>zu machen, nichtmal der Autor von Devel::Symdump.
> >>>
> >>>Vielleicht verstehst du jetzt, warum... ;-))
> >>
> >>Nein, eigentlich nicht. Wenn der Test gebraucht wird,
> >>muss man ihn irgendwie implementieren. Oder man lässt es
> >>und stellt die damit zusammenhängende Funktionalität
> >>nicht bereit. Oder man weist unter BUGS auf die
> >>entsprechenden Defizite hin.
> >
> > Wo ist der Bug? "Devel::Symdump - dump symbol names or the symbol
> > table"
>
> #!/usr/local/bin/perl -w
>
> use strict;
> use Devel::Symdump;
>
> package P;
>
> our ($x,@y,%z);
>
> package main;
>
> my $stash = Devel::Symdump->new('P');
> for my $scalar ($stash->scalars)
> {
> print $scalar,"\n";
> }
> __END__
> P::y
> P::x
> P::z
>

Das ist der Inhalt der Symboltabelle.

--
Slaven Rezic - slaven rezic de

tknotes - A knotes clone, written in Perl/Tk.
http://ptktools.sourceforge.net/#tknotes

Re: Existenz eines Skalar prüfen

am 06.12.2006 11:43:54 von Frank Seitz

Slaven Rezic wrote:
> Frank Seitz writes:
>>Slaven Rezic wrote:
>>>
>>>Wo ist der Bug? "Devel::Symdump - dump symbol names or the symbol
>>>table"
>>
>>#!/usr/local/bin/perl -w
>>
>>use strict;
>>use Devel::Symdump;
>>
>>package P;
>>
>>our ($x,@y,%z);
>>
>>package main;
>>
>>my $stash = Devel::Symdump->new('P');
>>for my $scalar ($stash->scalars)
>>{
>> print $scalar,"\n";
>>}
>>__END__
>>P::y
>>P::x
>>P::z
>
> Das ist der Inhalt der Symboltabelle.

Es sollte aber die Liste der skalaren Variablen,
mit dem einzigen Element P::x, sein.
Wenn Dich das Ergebnis wundert, stöbere mal in
diesem Thread, insbesondere in meiner ersten Antwort
hatte ich den Grund schon genannt.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Existenz eines Skalar prüfen

am 07.12.2006 00:36:18 von Slaven Rezic

Frank Seitz writes:

> Slaven Rezic wrote:
> > Frank Seitz writes:
> >>Slaven Rezic wrote:
> >>>
> >>>Wo ist der Bug? "Devel::Symdump - dump symbol names or the symbol
> >>>table"
> >>
> >>#!/usr/local/bin/perl -w
> >>
> >>use strict;
> >>use Devel::Symdump;
> >>
> >>package P;
> >>
> >>our ($x,@y,%z);
> >>
> >>package main;
> >>
> >>my $stash = Devel::Symdump->new('P');
> >>for my $scalar ($stash->scalars)
> >>{
> >> print $scalar,"\n";
> >>}
> >>__END__
> >>P::y
> >>P::x
> >>P::z
> >
> > Das ist der Inhalt der Symboltabelle.
>
> Es sollte aber die Liste der skalaren Variablen,
> mit dem einzigen Element P::x, sein.
> Wenn Dich das Ergebnis wundert, stöbere mal in
> diesem Thread, insbesondere in meiner ersten Antwort
> hatte ich den Grund schon genannt.

Der Bug ist vielleicht in Perl, aber nicht im Modul. Das Modul bildet
nur die Symboltabelle ab und verlässt sich darauf, was Perl
zurückgibt.

Gruß,
Slaven

--
Slaven Rezic - slaven rezic de

Start a WWW browser - OS independent:
http://user.cs.tu-berlin.de/~eserte/src/perl/WWWBrowser/

Re: Existenz eines Skalar prüfen

am 07.12.2006 09:16:54 von Ferry Bolhar

Frank Seitz:

> Folgender Code scheint das Gewünschte zu leisten
> (implementiert nach der Idee von Daniel Fischer):

> our $x;
> our $y;
> our @y;
> our @z;
> our %z;

[...]

Dieser Code basiert aber darauf, dass alle globalen Variablen
mit "our" deklariert werden! Da "our" noch relativ neu ist, gibt
es vermutlich viel älteren Modulcode, der noch mit "use vars"
globale Variablen deklariert (falls überhaupt).

Wenn du die Prüfung auf benutzte Paketskalare nur in eigenen
Modulen machen möchtest (und darin überall "our" verwendest),
dann wird's so klappen. Bei meinen, teilweise noch unter 5.004
und 5.005 entwickelten Modulen hättest du damit Pech.

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: Existenz eines Skalar prüfen

am 07.12.2006 10:05:11 von Frank Seitz

Slaven Rezic wrote:
> Frank Seitz writes:

>>>>P::y
>>>>P::x
>>>>P::z
>>>
>>>Das ist der Inhalt der Symboltabelle.
>>
>>Es sollte aber die Liste der skalaren Variablen,
>>mit dem einzigen Element P::x, sein.
>>Wenn Dich das Ergebnis wundert, stöbere mal in
>>diesem Thread, insbesondere in meiner ersten Antwort
>>hatte ich den Grund schon genannt.
>
> Der Bug ist vielleicht in Perl, aber nicht im Modul. Das Modul bildet
> nur die Symboltabelle ab und verlässt sich darauf, was Perl
> zurückgibt.

Nicht, dass ich das Verhalten von Perl an dieser Stelle gut finde
oder auch nur verstehe, aber es ist so dokumentiert:

| *foo{THING} returns undef if that particular THING hasn't
| been used yet, except in the case of scalars. *foo{SCALAR}
| returns a reference to an anonymous scalar if $foo hasn't
| been used yet. This might change in a future release.

Insofern liegt das Problem klar auf Seite des Moduls.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Existenz eines Skalar prüfen

am 07.12.2006 10:07:05 von Frank Seitz

Ferry Bolhar wrote:
> Frank Seitz:
>>
>>Folgender Code scheint das Gewünschte zu leisten
>>(implementiert nach der Idee von Daniel Fischer):
>>
>>our $x;
>>our $y;
>>our @y;
>>our @z;
>>our %z;
>
> Dieser Code basiert aber darauf, dass alle globalen Variablen
> mit "our" deklariert werden!

Nein, wie kommst Du darauf?

> Da "our" noch relativ neu ist, gibt
> es vermutlich viel älteren Modulcode, der noch mit "use vars"
> globale Variablen deklariert (falls überhaupt).

Mit "use vars" geht es genauso. Ich persönlich verwende
dieses Konstrukt nur nicht mehr.

> Wenn du die Prüfung auf benutzte Paketskalare nur in eigenen
> Modulen machen möchtest (und darin überall "our" verwendest),
> dann wird's so klappen. Bei meinen, teilweise noch unter 5.004
> und 5.005 entwickelten Modulen hättest du damit Pech.

An "use vars" sollte es wie gesagt nicht scheitern.
Aber auf so asbachuralte Versionen nehme ich sowieso
keine Rücksicht mehr, dazu hat es in Perl seitdem zu viele
interessante Neuerungen gegeben.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Existenz eines Skalar prüfen

am 07.12.2006 12:01:53 von Ferry Bolhar

Frank Seitz:

>> Dieser Code basiert aber darauf, dass alle globalen Variablen
>> mit "our" deklariert werden!
>
> Nein, wie kommst Du darauf?

Ja, wie komme ich nur darauf? War ein Irrtum, sorry.

> Mit "use vars" geht es genauso. Ich persönlich verwende
> dieses Konstrukt nur nicht mehr.

Ja, der Hack ist gut - man nützt aus, dass Perl bei einem
existierenden Typeglob, aber noch nicht importierten Wertetyp
mit "use strict" aufschreit. Gut ausgedacht - hätte mir, wo ich
ja erst darüber geschrieben hatte, auch einfallen können.

Ich habe übrigens vor etlichen Jahren ein Modul geschrieben,
das von einem gegebenen Typeglob zurückgibt, welche(r)
Wertetyp(en) bereits importiert ist/sind. Falls es von Interesse
ist, poste ich den Code (XS) hier gerne. Damit läßt sich dein
Problem ohne den "not imported"-Hack (der aber trotzdem
ein super Ansatz ist) lösen.

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: Existenz eines Skalar prüfen

am 07.12.2006 12:13:57 von Ferry Bolhar

Slaven Rezic:

>> Es sollte aber die Liste der skalaren Variablen,
>> mit dem einzigen Element P::x, sein.
>> Wenn Dich das Ergebnis wundert, stöbere mal in
>> diesem Thread, insbesondere in meiner ersten Antwort
>> hatte ich den Grund schon genannt.
>
> Der Bug ist vielleicht in Perl, aber nicht im Modul. Das Modul bildet
> nur die Symboltabelle ab und verlässt sich darauf, was Perl
> zurückgibt.

Ja - aber das, was Perl zurückgibt, ist nicht ident zu dem, was in
der Anleitung des Moduls (speziell zu der scalar()-Methode) steht.
Dass ich z.B. beim Durchlaufen der Haupttabelle (main) mit scalar()
auch

main::Devel::
main::DynaLoader::
main::Exporter::

zurückbekomme, also Stashes anderer Symboltabellen, ist sicher
nicht ok. Hier müsste das Modul Perl's Ungenauigkeit durch etwas
eigene Intelligenz kompensieren. Und - wie wir jetzt wissen - ist
das ja auch möglich.

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at