List Context erzwingen?

List Context erzwingen?

am 22.01.2008 17:14:16 von Ferry Bolhar

Hallo,

bekanntlich kann man mittels der scalar Funktion einen skalaren Kontext
erzwingen:

print @x; # Gibt die Element von @x aus
print scalar @x; # Gibt die Elementanzahl von @x aus

Ich bräuchte jetzt genau das Umgekehrte - das Erzwingen eines
Listenkontexts.

Ich habe eine Anweisung in der Form:

my $val = '/F:' . $option =~ /^Ref: (.+) / . 'DATA';

Ich binde den in der Regex gefundenen Wert an $1 und möchte dieses $1 mit
den beiden Stringliteralen vorher und nachher verknüpfen. Es wird aber nicht
$1 (das, wie sich beim Testen zeigt, den gewünschten Wert enthält), sondern
die Ziffer "1" eingesetzt. Klar - im skalaren Kontext (der durch den
Verknüpfungsoperator "." vorgegeben wird) gibt der Match-Operator die Anzahl
an Matches zurück, nicht die Matches selbst.

Klar, dass ich das zweizeilig auch schreiben kann. Aber gibt es eine
Möglichkeit, das wie angedeutet in einer Zeile zu formulieren?

Danke für eure Hilfe & schöne Grüße aus Wien,

Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: ferdinand.bolhar-nordenkampf@wien.gv.at

Re: List Context erzwingen?

am 22.01.2008 17:58:21 von Paul Hink

Ferry Bolhar wrote:

> bekanntlich kann man mittels der scalar Funktion einen skalaren
> Kontext erzwingen:
>
> print @x; # Gibt die Element von @x aus
> print scalar @x; # Gibt die Elementanzahl von @x aus
>
> Ich bräuchte jetzt genau das Umgekehrte - das Erzwingen eines
> Listenkontexts.

| There is no equivalent operator to force an expression to be
| interpolated in list context because in practice, this is never
| needed. If you really wanted to do so, however, you could use the
| construction "@{[ (some expression) ]}", but usually a simple "(some
| expression)" suffices.

Quelle: `perldoc -f scalar`

> Ich habe eine Anweisung in der Form:
>
> my $val = '/F:' . $option =~ /^Ref: (.+) / . 'DATA';
>
> Ich binde den in der Regex gefundenen Wert an $1 und möchte dieses $1
> mit den beiden Stringliteralen vorher und nachher verknüpfen.

my $val = '/F:' . ($option =~ /^Ref: (.+) /)[0] . 'DATA';

> Es wird aber nicht $1 (das, wie sich beim Testen zeigt, den
> gewünschten Wert enthält), sondern die Ziffer "1" eingesetzt. Klar -
> im skalaren Kontext (der durch den Verknüpfungsoperator "."
> vorgegeben wird) gibt der Match-Operator die Anzahl an Matches
> zurück, nicht die Matches selbst.

Laut Dokumentation gibt es True (wie z.B. 1) oder False zurück, nicht
irgendeine Anzahl:

| /PATTERN/cgimosx
| Searches a string for a pattern match, and in scalar
| context returns true if it succeeds, false if it fails.

Quelle: "Regexp Quote-Like Operators", perlop-Manpage

Re: List Context erzwingen?

am 22.01.2008 18:31:56 von Frank Seitz

Paul Hink wrote:
> Ferry Bolhar wrote:
>>
>>Ich habe eine Anweisung in der Form:
>>
>>my $val = '/F:' . $option =~ /^Ref: (.+) / . 'DATA';
>>
>>Ich binde den in der Regex gefundenen Wert an $1 und möchte dieses $1
>>mit den beiden Stringliteralen vorher und nachher verknüpfen.
>
> my $val = '/F:' . ($option =~ /^Ref: (.+) /)[0] . 'DATA';

Eine Argumentliste ist ebenfalls ein List-Kontext:

my $val = sprintf '/F:%sDATA', $option =~ /^Ref: (.+)/;

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: List Context erzwingen?

am 31.01.2008 15:33:07 von KWittrock

"Ferry Bolhar" schrieb im Newsbeitrag
news:1201018475.62417@proxy.dienste.wien.at...
> Hallo,
>
> bekanntlich kann man mittels der scalar Funktion einen skalaren Kontext
> erzwingen:
>
> print @x; # Gibt die Element von @x aus
> print scalar @x; # Gibt die Elementanzahl von @x aus
>
> Ich bräuchte jetzt genau das Umgekehrte - das Erzwingen eines
> Listenkontexts.
>
> Ich habe eine Anweisung in der Form:
>
> my $val = '/F:' . $option =~ /^Ref: (.+) / . 'DATA';

Der direkteste Weg scheint mir zu sein, den Listenkontext mit einem anonymen
Array zu erzwingen - wie in dem Zitat in Pauls Antwort vorgeschlagen - und
dieses sofort zu dereferenzieren:

my $val = '/F:' . ${[$option =~ /^Ref: (.+) /]}[0] . 'DATA';

Oder aber du arbeitest von vorn herein mit Listen, die du dann mit join
aneinanderhängst:

my $val = join('', '/F:', $option =~ /^Ref: (.+) /, 'DATA');

Gruß

Klaus

Re: List Context erzwingen?

am 31.01.2008 16:03:41 von Paul Hink

K. Wittrock wrote:

> Der direkteste Weg scheint mir zu sein, den Listenkontext mit einem
> anonymen Array zu erzwingen - wie in dem Zitat in Pauls Antwort
> vorgeschlagen - und dieses sofort zu dereferenzieren:
>
> my $val = '/F:' . ${[$option =~ /^Ref: (.+) /]}[0] . 'DATA';

Und das ist "direkter" als folgendes?

my $val = '/F:' . ($option =~ /^Ref: (.+) /)[0] . 'DATA';

Re: List Context erzwingen?

am 01.02.2008 08:55:38 von Ferry Bolhar

Paul Hink:

> Und das ist "direkter" als folgendes?
>
> my $val = '/F:' . ($option =~ /^Ref: (.+) /)[0] . 'DATA';

Ja, ich finde diese Syntax - wie auch die sprintf-Variante von
Frank Seitz - sehr einfach und intuitiv.

Ich habe mich letztlich für die von Paul entschieden, weil eine
ähnlich Syntax oft mit split verwendet wird, z.B:

my @vals = (split /../)[1,4..6,9];

und daher der Code für Andere (die ihn später warten müssen) lesbarer ist.

Nochmals danke für alle Antworten!

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: ferdinand.bolhar-nordenkampf@wien.gv.at