hotti: wantarray

Moin,

nachdem ich in den letzten Tagen festgestellt habe, dass wantarray in Perl eine ganz geniale Sache ist, wollte ich mal fragen, ob es sowas (ähnliches) auf für js gibt. Also ich hab da ein Objekt, das hat beispielsweise die Eigenschaften 'name' und 'vname'. Beim Befüllen des Objekts wird auf alle Eigenschaften ein push gemacht, genauso wie in Perl bei einem hash. Im Kontext   'name' wird dann nur ein Wert erwartet, wohingegen 'vname' auch mehrere Werte haben kann. Wie krieg ich das am Einfachsten raus?

Hotti

--
Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.
  1. Hallo,

    Im Kontext   'name' wird dann nur ein Wert erwartet, wohingegen 'vname' auch mehrere Werte haben kann. Wie krieg ich das am Einfachsten raus?

    perldoc sagt zu wantarray:

    Returns true if the context of the currently executing subroutine or eval is looking for a list value. Returns false if the context is looking for a scalar. Returns the undefined value if the context is looking for no value (void context).

    JavaScript kann keinen Kontext unterscheiden, also geht das so nicht.
    Den Kontext muss man beim Programmieren immer kennen und entsprechend coden.

    Gruß, Don P

  2. Hallo Rolf,

    nachdem ich in den letzten Tagen festgestellt habe, dass wantarray in Perl eine ganz geniale Sache ist, wollte ich mal fragen, ob es sowas (ähnliches) auf für js gibt. Also ich hab da ein Objekt, das hat beispielsweise die Eigenschaften 'name' und 'vname'. Beim Befüllen des Objekts wird auf alle Eigenschaften ein push gemacht, genauso wie in Perl bei einem hash. Im Kontext   'name' wird dann nur ein Wert erwartet, wohingegen 'vname' auch mehrere Werte haben kann. Wie krieg ich das am Einfachsten raus?

    mir ist auch schon bei Deinem letzten Problem nicht wirklich klar geworden, warum Du solche Umstände machst. Du gehst ja in beiden Fällen (hier und im alten post) vom Beispiel(?) Vorname aus. Dabei fängt mein Verständnisproblem an, wo Du ganz selbstverständlich mehrere Vornamen in ein Datenfeld gliedern willst. Belasse doch den Namen als ganzes. Bei der Verarbeitung nimmst Du whitespace als Delimiter. Somit stellt sich in beiden Sprachen (JS und Perl) die Frage nach dem richtigen Kontext nicht.

    Direkt zu Deiner Frage nach einem Adäquat in JS würde ich schlicht auf typeof zurückgreifen.

    Gruß aus Berlin!
    eddi

    1. Hallo,

      Dabei fängt mein Verständnisproblem an, wo Du ganz selbstverständlich mehrere Vornamen in ein Datenfeld gliedern willst. Belasse doch den Namen als ganzes.

      Ich habe es so verstanden, dass im Listenkontext der ganze Name (also z.B. das Objekt selber mit den beiden Eigenschaften name und vname) zurückgegeben weden soll, im scalaren Kontext aber nur der Name.

      Natürlich kann man dem Objekt eine Methode "wholename" oder so geben, die dann den ganzen Namen zurückgibt, als Array oder als Objekt oder als String, aber die müsste man dann explizit aufrufen. Der Vorteil von Perls wantarray wäre damit aber verloren.

      Gruß, Don P

      1. Hi,

        Natürlich kann man dem Objekt eine Methode "wholename" oder so geben, die dann den ganzen Namen zurückgibt, als Array oder als Objekt oder als String, aber die müsste man dann explizit aufrufen.

        Man könnte dem Objekt zumindest eine toString-Methode verpassen, die automatisch aufgerufen wird, wenn das Objekt bei der Ausgabe in einen String-Kontext überführt wird.

        MfG ChrisB

        --
        “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
  3. nachdem ich in den letzten Tagen festgestellt habe, dass wantarray in Perl eine ganz geniale Sache ist,

    wantarray ist in dem zusammenhang völlig belanglos, du hattest es schon in dem anderen Post alles durcheinander geworfen (deine Lösung hatte nicht mehr viel mit der ursprünglichen fragestellung zu tun). Mit wantarray kannst du Abfrage ob ein Funktionsaufruf in einen Array oder Skalaren Kontext steht.

    wollte ich mal fragen, ob es sowas (ähnliches) auf für js gibt. Also ich hab da ein Objekt, das hat beispielsweise die Eigenschaften 'name' und 'vname'. Beim Befüllen des Objekts wird auf alle Eigenschaften ein push gemacht, genauso wie in Perl bei einem hash. Im Kontext   'name' wird dann nur ein Wert erwartet, wohingegen 'vname' auch mehrere Werte haben kann. Wie krieg ich das am Einfachsten raus?

    Die Frage ist nicht klar. Ich kenn zwar deine Perl Frage zu dem Thema, aber an welcher Stelle hast du jetzt in JS damit ein Problem?
    Wenn vname ein Array ist dann schreibst du objekt.vname = ['wert1', 'wert2']; wenn nicht dann so objekt.vname = 'wert1';

    Wieso musst du jetzt, wo Wissen, ob die Eiegnschaft ein Array ist oder nicht? (Wobei ich aber auch denke, dass dies Art der Datenhaltung nicht sinnvoll ist.

    Struppi.

    1. hi,

      Die Frage ist nicht klar. Ich kenn zwar deine Perl Frage zu dem Thema, aber an welcher Stelle hast du jetzt in JS damit ein Problem?

      Es ist eigentlich kein Problem. Ich brauch das in meinem Framework falls ich mal ein Form aus einem Objekt zurückschreiben muss, was bisher jedoch noch nicht so als Aufgabe bestand.

      Ansonsten schau Dir mal an, wie ein Browser ein multiple select oder checkboxen sendet. Das zielt in Richtung serverseitigen Parser, der in solchen Fällen ein Array liefert (CGI.pm). Das ist also nichts Außergewöhnliches sondern in unserer langjährigen Praxis Gang und Gäbe.

      In meinem Framework (Ajax und CGI) hab ich diese Parsergeschichten nun glatt gezogen, es gibt für die Datenübertragung einen einheitlichen Layer one, egal ob Daten von XHR zum Server gehen oder umgekehrt. Was deratig einheitliche Prozesse hinsichtlich einer Rationalen Programmierung mit einem Framework bedeuten, muss ich wohl nicht näher erläutern ;-)

      Falls Du da noch Fragen hast, in meinem Artikel, Link obenstehend, findest Du die Antworten.

      Viele Grüße,
      Hotte

  4. Perl ist IMHO die einige Sprache mit solchen contexts.

    Du kannst etwas "ähnliches" mit stringification und nummification eines Objektes in JS haben, die entsprechenden Operatoren erzwingen eine implizite Wertumwandlung.

    Dafür müsstest du aber die entsprechenden Methoden im Prototyp deines "Hash"-Objectes überschreiben. Sodass du an den Stellen wo du den einzelnen Skalar haben möchtest syntaktisch ein String erzwungen wird.

    z.B. mit

    skalar=""+object  
    list=0+object  
    hash=object  
    
    

    (letzteres klont dann die werte in ein neues Array objekt)

    Das ist aber alles nicht sonderlich sinnig in JS, ein skalar könnte ja auch eine Zahl sein und dann .. ärgh...

    Die deutlich bessere Variante deinem Object eine Methode set() hinzuzufügen die die Zielvariable als Parameter erhält.

    Ist diese vom typ string wird nur ein Wert gesetzt, ansonsten ein array.

      
    obj.set(skalar)  
    obj.set(array)  
    
    

    Das ist dann auch auf beliebige Zielobjekte erweiterbar.

    Könnte man in JS die Zuweisung überladen wie in Perl (geht nicht) wärs vielleicht sogar möglich contexts zu emulieren.

    Vergiss aber nicht dass du in JS Arrays und andere Objecte als solche initialisieren musst damit die Erkennung klappt, weil es ja keine Sigils gibt.

    Also

    a=[]  
    a= new Array()  
    obj.set(a)  
    
    

    Ob dass nun alles so funktioniert wie du's gern hättest musst du selbst rausfinden...

    Was du also bei der Zuweisung einsparst, erzeugt neuen overhead, deswegen eröffnen sich in JS dadurch keine neuen Horizonte.

    Üblicherweise würde man viel eher sowas schreiben:

    skalar=obj.clone(name);  
    list=obj.clone(vname);  
    skalar=obj.name;  
    list=obj.vname;  
    
    

    Grüße
      Rolf

    1. Hi

      (letzteres klont dann die werte in ein neues Array objekt)

      um das klarer auszuarbeiten, JS kennt keine Listenzuweisung!

      ($a,$b)=(1,2)  
      
      

      geht nicht!

      erst recht nicht

      @vnamen=( "hugo", "alfred", "nepomuk")  
      
      

      in JS geht nur

      vnamen=["hugo", "alfred", "nepomuk"]  
      
      

      d.h. es werden keine Werte kopiert sondern ein neues Array erzeugt!!!

      Du kannst immer nur einen Wert zuweisen, um mehrere Werte zu transportieren muss dieser Wert ein Container wie z.B. ein Array sein.

      Und wo es keine Listen gibt, gibts auch keinen list context.

      (BTW: wir hatten mal die Diskussion wo die unterschied zw. Listen und Arrays in Perl sind, mit einem Listassign und Listvalue wird in den Opcodes angezeigt das mehrere Werte über den C-Stack geschoben werden sollen. Ein Array hingegen ist eine echte Variable, du siehts in JS können nur Arrays übergeben werden und keine Listen)

    2. ERRATA:

      z.B. mit

      skalar=""+object

      list=0+object
      hash=object

      
      >   
      > (letzteres klont dann die werte in ein neues Array objekt)  
        
      Ähm natürlich vorletzteres (JS kennt keine Listenzuweisungen)  
        
      
      > ~~~javascript
      
      a=[]  
      
      > a= new Array()  
      > obj.set(a)  
      > 
      
      

      Die Initialisierungen von a sind natürlich entweder/oder.