Frage(n) zur Manipulation von Arrays mit pop und und shift

Begonnen von TomLee, 09 Februar 2022, 23:06:47

Vorheriges Thema - Nächstes Thema

TomLee

Hatte mir heute ganz umständlich so ein Konstrukt ausgedacht um in einem notify bei $EVENT das erste Element zu entfernen, um etwas später zu merken das einfach nur das auslesen des Events mit ReadingsVal() der Weg ist  ::)

{my @ar=split ' ','bli bla blub';;shift @ar;;my $val = join ' ',@ar}

Mich beschäftigt aber immer noch dabei das man pop und shift nicht direkt auf das split anwenden kann, so gings viel kürzer :

{my $val = join ' ',shift split ' ','bli bla blub'}

Habs vorsichtshalber auch mit Klammern bei join und split probiert.

Kann man pop/shift nur auf die Variable selbst anwenden oder gibts da noch nen 'Trick' ?

Beta-User

Na ja, zumindest mein Perl mosert, dasss "experimental shift on scalar" verboten wäre...

Da ist aber auch auf alle Fälle ein Logikfehler drin, denn das shift liefert den entnommenen Wert, nicht die verbleibende Liste ;) .
In deinem Beispiel wäre das "bli" (wenn es denn funktionieren würde). Ergo: Man schreibe bitte aus, was man haben will, dann funktioniert Perl erwartungsgemäß und man kann es lesen...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

TomLee

ZitatNa ja, zumindest mein Perl mosert, dasss "experimental shift on scalar" verboten wäre...

Mein(e) Unverständnis/Frage zielt aber darauf das split ein Array zurückgibt und ich da nicht mitkomme warum es zu dem Zeitpunkt ein Scalar sein soll.
Darum die Frage ob man shift/pop nur auf die Variable selbst anwenden kann.

ZitatDa ist aber auch auf alle Fälle ein Logikfehler drin, denn das shift liefert den entnommenen Wert, nicht die verbleibende Liste ;) .

Warum ist da ein Logikfehler din ?

Ich will das erste Element "entnehmen" (verschieben) und die restlichen Elemente ausgebe, das klappt genauso wie oben gezeigt.

Nur "bli" würde doch so ausgegeben:

{my @ar=split ' ','bli bla blub';;my $fe=shift @ar;;return $fe}


Beta-User

Zitat von: TomLee am 10 Februar 2022, 11:13:06
Mein(e) Unverständnis/Frage zielt aber darauf das split ein Array zurückgibt und ich da nicht mitkomme warum es zu dem Zeitpunkt ein Scalar sein soll.
Diese Rückmeldung finde ich auch nicht unbedingt logisch, es kann aber sein, dass erst durch die Zuweisung zu einem bestimmten Variablentyp klar ist, ob es SCALAR oder ARRAY sein soll... Anders gesagt: Die Meldung würde in der vorliegenden Form keinen Sinn machen, wenn es nicht mal funktioniert hätte (früher).

Zitat
Darum die Frage ob man shift/pop nur auf die Variable selbst anwenden kann.
Eher: man kann es nur verwenden, wenn man sicher ist, dass es ein Array ist.

ZitatWarum ist da ein Logikfehler din ?
Bezugspunkt war:
{my $val = join ' ',shift split ' ','bli bla blub'}Das join bezieht sich so rein semantisch auf die letzte Anweisung, also den geshifteten Wert, nicht auf den Rest.
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

TomLee

ZitatDas join bezieht sich so rein semantisch auf die letzte Anweisung, also den geshifteten Wert, nicht auf den Rest.

Folgen kann ich dir schon, aber verstehen, wie du es siehst, (noch) nicht.

Hier:
{my @ar=split ' ','bli bla blub';;shift @ar;;my $val = join ' ',@ar}

bezieht sich join auch nur auf die letzte Anweisung -> shift @ar

Nix anderes wie (mal mit Klammern), rein semantisch -> shift split(' ','bli bla blub')

oder gar so -> shift (split(' ','bli bla blub'))

Demnach liefert shift <ARRAY> die verbliebenen Werte und nicht den entnommenen.

Beta-User

Zitat von: TomLee am 10 Februar 2022, 12:48:37

Folgen kann ich dir schon, aber verstehen, wie du es siehst, (noch) nicht.

Hier:
{my @ar=split ' ','bli bla blub';;shift @ar;;my $val = join ' ',@ar}

bezieht sich join auch nur auf die letzte Anweisung -> shift @ar
Nein. join wird mit @ar vollzogen.

Zitat
Demnach liefert shift <ARRAY> die verbliebenen Werte und nicht den entnommenen.
Nein. @blub sei ein Array mit einigen Elementen. "my $bla = shift @blub;" macht zwei Dinge:
a) $bla wird mit dem aus dem Array gelöschten Wert befüllt;
b) @blub ist hinterher ein Element kleiner.
Mit beiden Teilen kann man hinterher weiter agieren.
join q{ }, $bla;
und join q{ }, @blub;
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

TomLee

#6
Sry, war kurz beschäftigt, meine Mutter wollte unbedingt das ich heute ihre Essküche streiche.




Komm immer noch nicht mit.

Hier:

Zitat{my @ar=split ' ','bli bla blub';;shift @ar;;my $val = join ' ',@ar}

wird join nicht mit @ar vollzogen, sondern mit dem Rückgabewert von shift, hast das mal in die Kommandozeile gekippt ?
Wenn das so wäre würden ja alle drei Elemente zurückgegeben.

Zu deinem letzten Beispiel: join q{ }, $bla;

Wozu join nehmen ?
Das geht, hab ich nachvollzogen, aber ist das nicht einfach nur ein Skalar (1.Element) der in $bla steckt, es reicht doch einfach ein print/return ?

{my @ar=split ' ','bli bla blub';;my $bla = shift @ar;;join q{ }, $bla}
bli
{my @ar=split ' ','bli bla blub';;my $bla = shift @ar;;return $bla}
bli

Beta-User

Zitat von: TomLee am 10 Februar 2022, 16:25:12
wird join nicht mit @ar vollzogen, sondern mit dem Rückgabewert von shift, hast das mal in die Kommandozeile gekippt ?
Jetzt ja. Erwartungsgemäß liefert es die letzten beiden Elemente:
Zitatbla blub
ZitatZu deinem letzten Beispiel: join q{ }, $bla;

Wozu join nehmen ?
...ist doch nur ein Beispiel, um es klarer zu machen. Klar ist das bei einem SCALAR unnötig. Das erste Element könnte aber auch ein ARRAY gewesen sein, da ginge es (uU. mit etwas "Umsiegelung")...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

TomLee

Zitat... dass erst durch die Zuweisung zu einem bestimmten Variablentyp klar ist, ob es SCALAR oder ARRAY sein soll... Anders gesagt: Die Meldung würde in der vorliegenden Form keinen Sinn machen, wenn es nicht mal funktioniert hätte (früher).

Dazu hab ich noch was, bin gespannt was du weiter zu sagst.

Ich übergeb doch eine Array sonst ging das doch gar nicht  ::) 8) ;D

{ my $aref  = \split ' ','bli bla blub';;ref $aref }

herrmannj

#9
so gehts (zu deiner ursprünglichen Frage) :
join(' ', @ar[1..$#ar-1]);

TomLee

Zitat von: herrmannj am 10 Februar 2022, 21:33:23
so gehts (zu deiner ursprünglichen Frage) :
join(' ', @ar[1..$#ar-1]);

Ja, sehr, sehr cool und Danke, weiß ich zu schätzen, das ist meine Variante:
{my @ar=split ' ','bli bla blub';;shift @ar;;my $val = join ' ',@ar}

nur kürzer:
{my @ar =split ' ','bli bla blub';;join(' ', @ar[1..$#ar-1])}

Es ist aber nicht die Antwort auf die ursprüngliche Frage.

Die Frage war und ist immer noch, warum man pop und shift nicht direkt auf split anwenden kann und nur über die Variable selbst.

Jörg hat mich mit dieser Aussage :

Zitates kann aber sein, dass erst durch die Zuweisung zu einem bestimmten Variablentyp klar ist, ob es SCALAR oder ARRAY sein soll... Anders gesagt: Die Meldung würde in der vorliegenden Form keinen Sinn machen, wenn es nicht mal funktioniert hätte (früher).

verstanden, mein ich.

Zeigt doch auch meine letztes Beispiel das da irgendwas (in Perl) nicht passt:

{ my $aref  = \split ' ','bli bla blub';;ref $aref }

Die Referenz auf ein Array ergibt SCALAR ?