NAME
Quiq::Json - Erzeuge JSON-Code in Perl
BASE CLASS
SYNOPSIS
Klasse laden und Objekt instantiieren
use Quiq::Json;
my $j = Quiq::Json->new;
JSON-Objekt via object()
$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-Datenstruktur via encode()
$json = $j->encode({
pi => 3.14159,
str => 'Hello world!',
bool => \'true',
obj => {
id => 4711,
name => 'Wall',
numbers => [1..5],
},
min => undef,
});
erzeugt
{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 :
DESCRIPTION
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.)lesbarerer Code
EXAMPLE
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,
),
)],
),
),
);
erzeugt
{
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',
},
}],
},
},
}
METHODS
Instantiierung
new() - Konstruktor
Synopsis
$j = $class->new(@keyVal);
Attributes
Returns
Objekt
Description
Instantiiere ein Objekt der Klasse und liefere eine Referenz auf dieses Objekt zurück.
Objektmethoden
code() - Erzeuge Sourcecode für JSON-Datenstruktur
Synopsis
$code = $j->code($text); # Scalar-Kontext
($codeS) = $j->code($text); # List-Kontext
Alias
c()
Arguments
Returns
Sourecode (String). Im List-Kontext eine Referenz auf den Code.
Description
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
Example
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;
},
}
encode() - Wandele Perl- in JavaScript-Datenstruktur
Synopsis
$json = $j->encode($scalar);
Arguments
- $scalar
-
Skalarer Wert: undef, \0, \1, Number, String, String-Referenz, Array-Referenz, Hash-Referenz.
Returns
JSON-Code (String)
Description
Wandele $scalar nach JSON und liefere den resultierenden Code zurück. Die Übersetzung erfolgt (rekursiv) nach folgenden Regeln:
- undef
-
Wird abgebildet auf:
undefined
. In einem Objekt wird das betreffende Attribut weggelassen. - \1 oder \'true'
-
Wird abgebildet auf:
true
- \0 oder \'false'
-
Wird abgebildet auf:
false
- NUMBER
-
Wird unverändert übernommen: NUMBER
- STRING
-
Wird abgebildet auf: 'STRING'
- STRING_REF
-
Wird abgebildet auf: STRING (literale Einsetzung von STRING)
Dies ist z.B. nützlich, wenn ein Teil der Datenstruktur abweichend formatiert werden soll.
- ARRAY_REF
-
Wird abgebildet auf: [ELEMENT1,ELEMENT2,...]
- HASH_REF
-
Wird abgebildet auf: {KEY1:VALUE1,KEY2:VALUE2,...}. Im Falle des Werts undef, wird das betreffende Schlüssel/Wert-Paar weggelassen.
object() - Erzeuge Code für JSON-Objekt
Synopsis
$json = $j->object(@opt,@keyVal); # Scalar-Kontext
($jsonS) = $j->object(@opt,@keyVal); # List-Kontext
Alias
o()
Arguments
Options
Returns
JSON-Code (String). Im List-Kontext eine Referenz auf den Code.
Description
Erzeuge den Code für ein JSON-Objekt mit den Attribut/Wert-Paaren @keyVal und liefere diesen zurück.
Hilfsmethoden
key() - Schlüssel eines JSON-Objekts
Synopsis
$str = $j->key($key);
Arguments
Returns
String
Description
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.
Example
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'"
VERSION
1.222
AUTHOR
Frank Seitz, http://fseitz.de/
COPYRIGHT
Copyright (C) 2024 Frank Seitz
LICENSE
This code is free software; you can redistribute it and/or modify it under the same terms as Perl itself.