Quiq::Json - Erzeuge JSON-Code in Perl
Quiq::Hash
use Quiq::Json; my $j = Quiq::Json->new;
$json = $j->object( pi => 3.14159, str => 'Hello world!', bool => \'true', obj => $j->object( id => 4711, name => 'Wall', numbers => [1..5], ), min => undef, );
erzeugt
{ pi: 3.14159, str: 'Hello world!', bool: true, obj: { id: 4711, name: 'Wall', numbers: [1,2,3,4,5], }, min: undefined, }
Bei der Methode $j->object()
bleibt die Reihenfolge der Schlüssel/Wert-Paare erhalten
jedes Schlüssel/Wert-Paar beginnt auf einer eigenen Zeile und wird eingerückt
$json = $j->encode({ pi => 3.14159, str => 'Hello world!', bool => \'true', obj => { id => 4711, name => 'Wall', numbers => [1..5], }, min => undef, });
{bool:true,min:undefined,obj:{id:4711,name:'Wall',numbers:[1,2,3,4,5]},pi:3.14159,str:'Hello world!'}
Bei der Methode $j->encode()
werden die Schlüssel/Wert-Paare von JSON-Objekten alphanumerisch sortiert (bei {...} ist die Reihenfolge sonst undefiniert)
gibt es keine Einrückung oder Leerraum nach dem :
Die Klasse ermöglicht die präzise Erzeugung von JavaScript-Datenstrukturen aus Perl heraus. Der Fokus liegt nicht auf der Übermittlung von Daten, sondern auf der Einsetzung der Strukturen in JavaScript-Quelltexte. Insofern gehen die Möglichketen der Klasse über JSON hinaus. Die JavaScript-Klasse Chart.js arbeitet z.B. mit einer komplexen Datenstruktur. Diese Struktur aus Perl heraus dynamisch erzeugen zu können, war der Anlass für die Entwicklung dieser Klasse. Das Perl-Modul JSON ist für diese Zwecke nicht geeignet, denn z.B. kann eine JavaScript-Datenstruktur Referenzen auf (inline definierte) JavaScript-Funktionen enthalten. Dies ist mit dieser Klasse möglich. Weitere Vorteile dieser Klasse:
die Reihenfolge von Objektattributen bleibt erhalten
Werte können literal eingesetzt werden (z.B. Funktionsdefinionen, spezielle Werte wie true, false, null usw.)
true
false
null
lesbarerer Code
Ein realer Fall. Die Erzeugung einer Konfiguration für Chart.js. Wir nutzen hier die Aliase o() und c() für die Methoden object() und code().
my @dataSets; my $title = 'Windspeed'; my $unit = 'm/s'; my $tMin = undef; my $tMax = undef; my $yMin = 0; my $yMax = undef; $json = $j->o( type => 'line', data => $j->o( datasets => \@dataSets, ), options => $j->o( maintainAspectRatio => \'false', title => $j->o( display => \'true', text => $title, fontSize => 16, fontStyle => 'normal', ), tooltips => $j->o( intersect => \'false', displayColors => \'false', backgroundColor => 'rgb(0,0,0,0.6)', titleMarginBottom => 2, callbacks => $j->o( label => $j->c(qq~ function(tooltipItem,data) { var i = tooltipItem.datasetIndex; var label = data.datasets[i].label || ''; if (label) label += ': '; label += tooltipItem.value + ' $unit'; return label; } ~), ), ), legend => $j->o( display => \'false', ), scales => $j->o( xAxes => [$j->o( type => 'time', ticks => $j->o( minRotation => 30, maxRotation => 60, ), time => $j->o( min => $tMin, max => $tMax, minUnit => 'second', displayFormats => $j->o( second => 'YYYY-MM-DD HH:mm:ss', minute => 'YYYY-MM-DD HH:mm', hour => 'YYYY-MM-DD HH', day => 'YYYY-MM-DD', week => 'YYYY-MM-DD', month => 'YYYY-MM', quarter => 'YYYY [Q]Q', year => 'YYYY', ), tooltipFormat => 'YYYY-MM-DD HH:mm:ss', ), )], yAxes => [$j->o( ticks => $j->o( min => $yMin, max => $yMax, ), scaleLabel => $j->o( display => \'true', labelString => $unit, ), )], ), ), );
{ type: 'line', data: { datasets: [], }, options: { maintainAspectRatio: false, title: { display: true, text: 'Windspeed', fontSize: 16, fontStyle: 'normal', }, tooltips: { intersect: false, displayColors: false, backgroundColor: 'rgb(0,0,0,0.6)', titleMarginBottom: 2, callbacks: { label: function(tooltipItem,data) { var i = tooltipItem.datasetIndex; var label = data.datasets[i].label || ''; if (label) label += ': '; label += tooltipItem.value + ' m/s'; return label; }, }, }, legend: { display: false, }, scales: { xAxes: [{ type: 'time', ticks: { minRotation: 30, maxRotation: 60, }, time: { min: undefined, max: undefined, minUnit: 'second', displayFormats: { second: 'YYYY-MM-DD HH:mm:ss', minute: 'YYYY-MM-DD HH:mm', hour: 'YYYY-MM-DD HH', day: 'YYYY-MM-DD', week: 'YYYY-MM-DD', month: 'YYYY-MM', quarter: 'YYYY [Q]Q', year: 'YYYY', }, tooltipFormat: 'YYYY-MM-DD HH:mm:ss', }, }], yAxes: [{ ticks: { min: 0, max: undefined, }, scaleLabel: { display: true, labelString: 'm/s', }, }], }, }, }
$j = $class->new(@keyVal);
Tiefe der Einrückung.
Objekt
Instantiiere ein Objekt der Klasse und liefere eine Referenz auf dieses Objekt zurück.
$code = $j->code($text); # Scalar-Kontext ($codeS) = $j->code($text); # List-Kontext
c()
Sourcecode, typischerweise mehrzeiliger JavaScript-Code.
Sourecode (String). Im List-Kontext eine Referenz auf den Code.
Erzeuge Sourcecode, der in eine JSON-Datenstruktur eingebettet werden kann, und liefere diesen zurück. Der Code
erhält die richtige Einrückung
wird "as is" eingebettet, also nicht gequotet
Weise Funktionsreferenz an Objekt-Attribut zu
$unit = 'm/s'; $json = $j->object( label => $j->code(qq~ function(tooltipItem,data) { var i = tooltipItem.datasetIndex; var label = data.datasets[i].label || ''; if (label) label += ': '; label += tooltipItem.value + ' $unit'; return label; } ~), ),
liefert
{ label: function(tooltipItem,data) { var i = tooltipItem.datasetIndex; var label = data.datasets[i].label || ''; if (label) label += ': '; label += tooltipItem.value + ' m/s'; return label; }, }
$json = $j->encode($scalar);
Skalarer Wert: undef, \0, \1, Number, String, String-Referenz, Array-Referenz, Hash-Referenz.
JSON-Code (String)
Wandele $scalar nach JSON und liefere den resultierenden Code zurück. Die Übersetzung erfolgt (rekursiv) nach folgenden Regeln:
Wird abgebildet auf: undefined. In einem Objekt wird das betreffende Attribut weggelassen.
undefined
Wird abgebildet auf: true
Wird abgebildet auf: false
Wird unverändert übernommen: NUMBER
Wird abgebildet auf: 'STRING'
Wird abgebildet auf: STRING (literale Einsetzung von STRING)
Dies ist z.B. nützlich, wenn ein Teil der Datenstruktur abweichend formatiert werden soll.
Wird abgebildet auf: [ELEMENT1,ELEMENT2,...]
Wird abgebildet auf: {KEY1:VALUE1,KEY2:VALUE2,...}. Im Falle des Werts undef, wird das betreffende Schlüssel/Wert-Paar weggelassen.
$json = $j->object(@opt,@keyVal); # Scalar-Kontext ($jsonS) = $j->object(@opt,@keyVal); # List-Kontext
o()
Liste der Schlüssel/Wert-Paare
Rücke die Elemente des Hash ein.
JSON-Code (String). Im List-Kontext eine Referenz auf den Code.
Erzeuge den Code für ein JSON-Objekt mit den Attribut/Wert-Paaren @keyVal und liefere diesen zurück.
$str = $j->key($key);
Schlüssel.
String
Erzeuge den Code für den Schlüssel $key eines JSON-Objekts und liefere diesen zurück. Enthält der Schlüssel nur Zeichen, die in einem JavaScript-Bezeichner vorkommen dürfen, wird er unverändert geliefert, ansonsten wird er in einfache Anführungsstriche eingefasst.
Schlüssel aus dem Zeichenvorrat eines JavaScript-Bezeichners:
$str = $j->Quiq::Json('borderWidth'); ==> "borderWidth"
Schlüssel mit Zeichen, die nicht in einem JavaScript-Bezeichner vorkommen:
$str = $j->Quiq::Json('border-width'); ==> "'border-width'"
1.174
Frank Seitz, http://fseitz.de/
Copyright (C) 2020 Frank Seitz
This code is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
To install Quiq, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Quiq
CPAN shell
perl -MCPAN -e shell install Quiq
For more information on module installation, please visit the detailed CPAN module installation guide.