Existenz eines Skalar prüfen

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
Frank Seitz [ Fr, 01 Dezember 2006 16:19 ] [ ID #1554635 ]

Re: Existenz eines Skalar prüfen

Frank Seitz <devnull4711 [at] web.de> 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 <at> rezic <dot> de

Lost in your Tk widget tree? Try
http://user.cs.tu-berlin.de/~eserte/src/perl/Tk-WidgetDump/
Slaven Rezic [ Fr, 01 Dezember 2006 23:59 ] [ ID #1554637 ]

Re: Existenz eines Skalar prüfen

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 [at] adv.magwien.gv.at
Ferry Bolhar [ Mo, 04 Dezember 2006 08:58 ] [ ID #1557090 ]

Re: Existenz eines Skalar prüfen

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
Mirco Wahab [ Mo, 04 Dezember 2006 10:39 ] [ ID #1557091 ]

Re: Existenz eines Skalar prüfen

Slaven Rezic wrote:
> Frank Seitz <devnull4711 [at] web.de> 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
Frank Seitz [ Mo, 04 Dezember 2006 13:30 ] [ ID #1557094 ]

Re: Existenz eines Skalar prüfen

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
Frank Seitz [ Mo, 04 Dezember 2006 13:30 ] [ ID #1557095 ]

Re: Existenz eines Skalar prüfen

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 [at] 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
Frank Seitz [ Mo, 04 Dezember 2006 13:31 ] [ ID #1557096 ]

Re: Existenz eines Skalar prüfen

Frank Seitz <devnull4711 [at] web.de> 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 [at] i;

[at] 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
Robert Sedlacek [ Mo, 04 Dezember 2006 13:48 ] [ ID #1557097 ]

Re: Existenz eines Skalar prüfen

Robert 'phaylon' Sedlacek wrote:
> Frank Seitz <devnull4711 [at] web.de> wrote
>>
>>Das funktionuckelt nicht zuverlässig. Gegenbeispiel:
>>
>>package B;
>>our [at] i;
>
> [at] 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
Frank Seitz [ Mo, 04 Dezember 2006 13:51 ] [ ID #1557098 ]

Re: Existenz eines Skalar prüfen

Frank Seitz <devnull4711 [at] web.de> wrote
> Robert 'phaylon' Sedlacek wrote:
> > Frank Seitz <devnull4711 [at] web.de> wrote
> >>
> >>Das funktionuckelt nicht zuverlässig. Gegenbeispiel:
> >>
> >>package B;
> >>our [at] i;
> >
> > [at] 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
Robert Sedlacek [ Mo, 04 Dezember 2006 14:26 ] [ ID #1557099 ]

Re: Existenz eines Skalar prüfen

Frank Seitz wrote:
> Robert 'phaylon' Sedlacek wrote:
>> Frank Seitz <devnull4711 [at] web.de> wrote
>>> Das funktionuckelt nicht zuverlässig. Gegenbeispiel:
>>>
>>> package B;
>>> our [at] i;
>> [at] i ist auch kein Skalar ;)
>
> Eben. :)

Dann musst Du die Tippeltappeltour machen:

package B;
our $scalar = 'Bj';
our $wrong = undef;
our [at] 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.
Mirco Wahab [ Mo, 04 Dezember 2006 14:23 ] [ ID #1557100 ]

Re: Existenz eines Skalar prüfen

Robert 'phaylon' Sedlacek wrote:
> Frank Seitz <devnull4711 [at] web.de> wrote
>>Robert 'phaylon' Sedlacek wrote:
>>>Frank Seitz <devnull4711 [at] web.de> wrote
>>>>
>>>>Das funktionuckelt nicht zuverlässig. Gegenbeispiel:
>>>>
>>>>package B;
>>>>our [at] i;
>>>
>>> [at] 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
Frank Seitz [ Mo, 04 Dezember 2006 14:34 ] [ ID #1557101 ]

Re: Existenz eines Skalar prüfen

Mirco Wahab wrote:

> Dann musst Du die Tippeltappeltour machen:
>
> package B;
> our $scalar = 'Bj';
> our $wrong = undef;
> our [at] 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 [at] 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
Frank Seitz [ Mo, 04 Dezember 2006 14:43 ] [ ID #1557102 ]

Re: Existenz eines Skalar prüfen

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 [at] 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;
[at] 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
Ch Lamprecht [ Mo, 04 Dezember 2006 14:46 ] [ ID #1557103 ]

Re: Existenz eines Skalar prüfen

Frank Seitz <devnull4711 [at] web.de> 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
Robert Sedlacek [ Mo, 04 Dezember 2006 14:46 ] [ ID #1557104 ]

Re: Existenz eines Skalar prüfen

Frank Seitz!

> Netter Einfall, ist aber auch zu kurz gedacht:

Ich will auch mal:

sub var_there($) {
my [at] var = split /::/, $_[0];
unshift [at] var, 'main' unless [at] var > 1;
my $var = pop [at] var;
my $pkg = join '::', [at] var;
open my $olderr, '>&', \*STDERR;
close STDERR;
my $err = '';
open STDERR, '>', \$err;
eval "{use strict; package $pkg; \$$var}";
my $err = $err || $ [at] ;
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
Daniel Fischer [ Mo, 04 Dezember 2006 14:54 ] [ ID #1557105 ]

Re: Existenz eines Skalar prüfen

Mirco Wahab schrieb:
> Frank Seitz wrote:
>> Robert 'phaylon' Sedlacek wrote:
>>> Frank Seitz <devnull4711 [at] web.de> wrote
>>>> Das funktionuckelt nicht zuverlässig. Gegenbeispiel:
>>>>
>>>> package B;
>>>> our [at] i;
>>> [at] 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, [at] 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
Christian Winter [ Mo, 04 Dezember 2006 14:54 ] [ ID #1557106 ]

Re: Existenz eines Skalar prüfen

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
Daniel Fischer [ Mo, 04 Dezember 2006 14:55 ] [ ID #1557107 ]

Re: Existenz eines Skalar prüfen

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
Christian Winter [ Mo, 04 Dezember 2006 15:28 ] [ ID #1557108 ]

Re: Existenz eines Skalar prüfen

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 [at] adv.magwien.gv.at
Ferry Bolhar [ Mo, 04 Dezember 2006 16:02 ] [ ID #1557109 ]

Re: Existenz eines Skalar prüfen

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 [at] 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.
Mirco Wahab [ Mo, 04 Dezember 2006 16:02 ] [ ID #1557110 ]

Re: Existenz eines Skalar prüfen

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
Frank Seitz [ Mo, 04 Dezember 2006 19:50 ] [ ID #1557112 ]

Re: Existenz eines Skalar prüfen

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 [at] ergn.l.hc/"
Ch Lamprecht [ Mo, 04 Dezember 2006 20:17 ] [ ID #1557113 ]

Re: Existenz eines Skalar prüfen

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
Daniel Fischer [ Di, 05 Dezember 2006 07:32 ] [ ID #1558263 ]

Re: Existenz eines Skalar prüfen

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
Frank Seitz [ Di, 05 Dezember 2006 10:09 ] [ ID #1558264 ]

Re: Existenz eines Skalar prüfen

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
Daniel Fischer [ Di, 05 Dezember 2006 10:13 ] [ ID #1558265 ]

Re: Existenz eines Skalar prüfen

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
Frank Seitz [ Di, 05 Dezember 2006 11:27 ] [ ID #1558266 ]

Re: Existenz eines Skalar prüfen

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
Frank Seitz [ Di, 05 Dezember 2006 11:30 ] [ ID #1558267 ]

Re: Existenz eines Skalar prüfen

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
Daniel Fischer [ Di, 05 Dezember 2006 11:49 ] [ ID #1558268 ]

Re: Existenz eines Skalar prüfen

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 [at] 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.:

[at] 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

[at] 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 [at] adv.magwien.gv.at
Ferry Bolhar [ Di, 05 Dezember 2006 12:12 ] [ ID #1558269 ]

Re: Existenz eines Skalar prüfen

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 [at] adv.magwien.gv.at
Ferry Bolhar [ Di, 05 Dezember 2006 12:13 ] [ ID #1558270 ]

Re: Existenz eines Skalar prüfen

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
Frank Seitz [ Di, 05 Dezember 2006 12:41 ] [ ID #1558271 ]

Re: Existenz eines Skalar prüfen

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, [at] 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
[at] 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 [at] adv.magwien.gv.at
Ferry Bolhar [ Di, 05 Dezember 2006 12:43 ] [ ID #1558272 ]

Re: Existenz eines Skalar prüfen

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, [at] 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
> [at] 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
Frank Seitz [ Di, 05 Dezember 2006 12:56 ] [ ID #1558273 ]

Re: Existenz eines Skalar prüfen

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
Frank Seitz [ Di, 05 Dezember 2006 13:14 ] [ ID #1558274 ]

Re: Existenz eines Skalar prüfen

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 [at] adv.magwien.gv.at
Ferry Bolhar [ Di, 05 Dezember 2006 16:34 ] [ ID #1558277 ]

Re: Existenz eines Skalar prüfen

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 [at] adv.magwien.gv.at
Ferry Bolhar [ Di, 05 Dezember 2006 16:42 ] [ ID #1558279 ]

Re: Existenz eines Skalar prüfen

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 [at] y;
our [at] 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) = [at] _;

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 $ [at] ;
}
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
Frank Seitz [ Di, 05 Dezember 2006 17:43 ] [ ID #1558280 ]

Re: Existenz eines Skalar prüfen

Frank Seitz!

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

<pan.2006.12.04.13.54.07.381951 [at] df.erinye.com>

Aber deins ist huebscher.


Gruß
Daniel
Daniel Fischer [ Di, 05 Dezember 2006 18:37 ] [ ID #1558281 ]

Re: Existenz eines Skalar prüfen

Frank Seitz <devnull4711 [at] web.de> 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 <at> rezic <dot> de

need xpm or ppm output from GD?
http://search.cpan.org/search?mode=module&query=GD::Convert
Slaven Rezic [ Di, 05 Dezember 2006 22:48 ] [ ID #1558283 ]
Perl » de.comp.lang.perl.misc » Existenz eines Skalar prüfen

Vorheriges Thema: Windows: lange Dateinamen
Nächstes Thema: fork pipe stdout Windows