Javacript get/set e UI

http://www.mitya.co.uk/blog/2012/Feb/ECMAScript-revolution-object-properties-201

ECMAScript 5: a revolution in object properties

Over the coming weeks I’m going to focus on discussing the mini revolution that ECMAScript 5 brought, and the implications in particular for objects and their properties.

ECMA5’s final draft was published at the end of 2009, but it was only really when IE9 launched in early 2011 – and, with it, impressive compatibility for ECMA5 – that it became a genuinely usable prospect. Now in 2012, it is being used more and more as browser vendors support it and its power becomes apparent. (Full ECMA5 compatibility table).

JavaScript has always been a bit of an untyped, unruly free-for-all. ECMAScript 5 remedies that somewhat by giving you much greater control over what, if anything, can happen to object properties once changed – and it’s this I’ll be looking at in this first post.

A new approach to object properties

In fact the whole idea of an object property has changed; it’s no longer a case of it simply being a name-value pairing – you can now dictate all sorts of configuration and behaviour for the property. The new configurations available to each property are:

  • value – the property’s value (obviously)
  • writable – whether the property can be overwritten
  • configurable – whether the property can be deleted or have its configuration properties changed
  • enumerable – whether it will show up in a for-in loop
  • get – a function to fire when the property’s value is read
  • set – a function to fire when the property’s value is set

Collectively, these new configuration properties are called a property’s descriptor. What’s vital to understand, though, is that some are incompatible with others.

Two flavours of objects

The extensive MDN article on ECMAScript 5 properties suggests thinking of object properties in two flavours:

  • data descriptors – a property that has a value. In its descriptor you can set value and writable but NOT get or set
  • accessor descriptors – a property described not by a value but by a pair of getter-setter functions. In its descriptor you can set get and set but NOT value or writable.

Note that enumerable and configurable are usable on both types of property. I’m struggling to understand why someone thought the ability to set a value and a setter function, for example, were incompatible desires. If I find out, I’ll let you know.

New methods

To harness this new power, you need to define properties in one of three ways – all stored as new static methods of the base Object object:

  • defineProperty()
  • defineProperties()
  • create()

The first two work identically except the latter allows you to set multiple properties in one go. As for Object.create(), I’ll be covering that separately in a forthcoming post.

Object.defineProperty() is arguably the most important part of this new ECMAScript spec; as John Resig points out in his post on the new features, practically every other new feature relies on this methd.

Object.defineProperty() accepts three arguments:

  • the object you wish to add a property to
  • the name of the property you wish to add
  • a descriptor object to configure the property (see descriptor properties above)

Let’s see it in action.

var obj1 = {};
Object.defineProperty(obj1, 'newProp', {value: 'new value', writable: false});
obj1.newProp = 'changed value';
console.log(obj1.newProp); //new value - no overwritten

See how the overwrite failed? No error or warning is thrown – it simply fails silently. In ECMA5’s new ‘strict mode’, though, it does throw an exception. (Thanks to Michiel van Eerd for pointing this out.)

There we set a data descriptor. Let’s set an accessor descriptor instead.

var obj = {}, newPropVal;
Object.defineProperty(obj, 'newProp', {
    get: function() { return newPropVal; },
    set: function(newVal) { newPropVal = newVal; }
});
obj.newProp = 'new val';
console.log(obj.newProp); //new val

You might be wondering what on earth is going on with that newPropVal variable. I’ll come to that in my next post which will look at getters and setters in detail. Note also how, with our setter, the new value is forwarded to it as its only argument, as you’d expect.

The fact that these properties can be set only via these methods means you cannot create them by hand or in JSON files. So you can’t do:

var obj = {prop: {value: 'some val', writable: false}}; //etc
obj.prop = 'overwritten'; //works; it's not write-protected

ECMA 5 properties don’t replace old-style ones

An important thing to understand early on is that this new form of ‘uber’ property is not the default. If you define properties in the old way, they will behave like before.

var obj = {prop: 'val'};
obj.prop = 'new val'; //overwritte - no problemo

Reporting back

Note that these new configuration properties are, once set, not available via the API; rather, they are remembered in the ECMAScript engine itself. So you can’t do this (using the example above):

console.log(obj1.newProp.writable); //error; newProp is not an object

Instead, you’ll be needing Object.getOwnPropertyDescriptor. This takes two arguments – the object in question and the property you want to know about. It returns the same descriptor object you set above, so something like:

{value: 'new value', writable: true, configurable: true, enumerable: true}

More to come..

So there you go – a very exciting mini revolution, as I said. This new breed of intelligent object property really is at the heart of arguably the most major shake-up to the language for a long time. Next week I’ll continue this theme – stay posted!

http://www.mitya.co.uk/blog/2012/Mar/JavaScript-getters-and-setters-varying-approaches-204

JavaScript getters and setters: varying approaches

Getters and setters are a means of providing an arm’s-length way of getting or setting certain data, whilst keeping private other data, and are common of most languages. In JavasScript, setters are also a good way of ensuring your UI stays up to date as your data changes, which I’ll show you an example implementation further down.

A new approach to getters and setters

The new approach looks like this, and can be used only on properties created via the new Object.create() and Object.definePropert[y/ies]() methods.

var dog = {}, name;
var name;
Object.defineProperty(dog, 'name', {
    get: function() { return name; },
    set: function(newName) { name = newName; }
});
dog.name = 'Fido';
alert(dog.name); //Fido

You’ll note that this approach requires the help of a ‘tracker variable’ (in our case name) via which the getter/setter reference the property’s value. This is to avoid maximum recursion errors that the following would cause:

...
    get: function() { return this.name; }, //MR error
...

That happens because we set a getter, via which any attempt to read the property is routed. Therefore, having the getter reference this.name is effectively asking the getter to call itself – endlessly. Likewise for a setter, if it tried to assign to this.name.

Since each property needs its own tracker, and you don’t want lots of variables flying around, it’s a good idea to use a closure when declaring several properties.

var dog = {}, props = {name: 'Fido', type: 'spaniel', age: 4};
for (var prop in props)
    (function() {
        var propVal = props[prop];
        Object.defineProperty(dog, prop, {
            get: function() { return propVal; },
            set: function(newVal) { propVal = newVal; }
        });
    })()
alert(dog.name+' is a '+dog.type); //Fido is a spaniel
dog.name = 'Rex';
alert(dog.name+' is age '+dog.age); //Rex is age 4

There, we declare what properties we want on our object, and some start values. The loop sets each property, and tracks its value via a private propVal variable in its closure.

One of the things I like about this new approach is you no longer have to call the getters/setters explicitly (as you did with previous implementations – see below) – they fire simply by talking to the property.

Admittedly this has its proponents and its opponents; those in favour say getters/setters should fire simply by calling/assigning to the property – not calling some special methods to do that. Those against normally point out that someone new to the code might be surprised to find that talking to a property in fact fires a function.

My take is that, as long as this is part of the spec, and your code is well documented, there can be few complaints with using the new implementation.

Other ways of doing getters/setters

In any case, I much prefer them to the implementation we got in JavaScript 1.5.

var dog = {
    type: 'Labrador',
    get foo() { return this.type; },
    set foo(newType) { this.type = newType; }
};
alert(dog.type); //Labrador
dog.foo = 'Rotweiller';
alert(dog.foo); //Rotweiller

I’ve never been in love with this approach, chiefly because you don’t deal directly with the property but with a proxy that represents its getter/setter callbacks – in the above example foo. The new approach does away with this; you call/assign to the property just as you would if there were no getters/setters in play, and the getter/setter callbacks kick in automatically – they are not referenced explicitly.

That said, one good point about this separation of property value from getter/setter is that the getter/setter can safely reference the property via this without the risk of recursion error, as befalls the new approach.

The older way

There’s also the depracated __defineGetter__() and __defineSetter__() technique.

var dog = {
    type: 'Labrador'    
};
dog.__defineGetter__('get', function() { return this.type; });
alert(dog.get); //Labrador

Once again you have to name your setters/getters. By far the most notable point about this approach, though, is you can assign getters/setters after assigning the property – not a super common desire, but useful any time you don’t want to or can’t alter the prototype. The other two implementations don’t allow you to do this, at least without a lot of reworking.

A final point about these latter implementations is that they don’t hijack control of your property like the new implementation does. That is, if a developer ignores them and manipulates the property directly, they can. This is not good news; if you defined getters/setters, you probably want them to run, not be bypassed.

var dog = {
    name: 'Henry',
    set foo(newName) { alert('Hi from the setter!'); this.name = newName; }
};
dog.name = 'Rex'; //setter bypassed; its alert doesn't fire

Setters and a responsive UI

As I mentioned in the intro, another role of getters in JavaScript can be to keep your UI up to date as your data changes. Frameworks like Backbone JS sell themselves heavily on this concept.

As the intro to the Backbone documentation points out, medium-large JavaScript applications can easily get bogged down with jQuery selectors and other means trying to keep your views in-sync with your data.

A getter can help here. Here’s something I cooked up:

Object.UIify = function(obj) {
    for(var property in obj) {
        var orig = obj[property];
        (function() {
            var propVal;
            Object.defineProperty(obj, property, {
                get: function() { return propVal; },
                set: (function(target) {
                    return function(newVal) {
                        propVal = newVal;
                        $(target).text(propVal);
                    };
                })(orig.target)
            });
        })()
        obj[property] = orig.val;
    }
return obj;
};

$(function() {
    var dog = Object.UIify({name: {val: 'Fido', target: '#name'}, type: {val: 'Labrador', target: '#type'}});
    dog.name = 'Bert';
    dog.type = 'Rotweiller';
});

And here’s some example HTML:

<p id='dog'>Hi - my name's <span id='name'></span> and I'm a <span id='type'></span>!</p>

I’ll go into the details of what my method does in a further post. Essentially, though, what’s happening is we pass an object to the UIify() method where each property is a sub-object containing its starting value (val) and a CSS/jQuery selector pointing to to the UI element that should be updated as and when the value changes (target.)

UIify() then returns an object using the new ECMA5 getters/setters. Whenever a property of the object is overwritten, the corresponding UI element denoted by the target we specified is updated. In my case, the targets were simply elements with IDs, but it could of course be more complex targets – it’s just CSS/jQuery selector syntax.

———

So there you have it, three approaches through the ages. Next time up I’ll be looking more at the new Object funcionality in ECMA5.

(p.s. for further reading, be sure to check out the extensive MDN article on working with objects, which talks a lot about getter/setter techniques.)

Conversione da FLAC a MP3

Aggiorno il vecchio post https://fcel2008.wordpress.com/2011/01/15/conversione-di-piu-files-audio-flac-in-mp3-con-lame/ con un nuovo script tratto da https://wiki.archlinux.org/index.php/Convert_Flac_to_Mp3

#! /bin/sh

for a in *.flac; do
    OUTF=${a%.flac}.mp3

    ARTIST=`metaflac "$a" --show-tag=ARTIST | sed s/.*=//g`
    TITLE=`metaflac "$a" --show-tag=TITLE | sed s/.*=//g`
    ALBUM=`metaflac "$a" --show-tag=ALBUM | sed s/.*=//g`
    GENRE=`metaflac "$a" --show-tag=GENRE | sed s/.*=//g`
    TRACKNUMBER=`metaflac "$a" --show-tag=TRACKNUMBER | sed s/.*=//g`
    DATE=`metaflac "$a" --show-tag=DATE | sed s/.*=//g`

    flac -c -d "$a" | lame --noreplaygain -V0 \
        --add-id3v2 --pad-id3v2 --ignore-tag-errors --tt "$TITLE" --tn "${TRACKNUMBER:-0}" \
        --ta "$ARTIST" --tl "$ALBUM" --ty "$DATE" --tg "${GENRE:-12}" \
        - "$OUTF"
    RESULT=$?
    if [ "$1" ] && [ "$1" = "-d" ] && [ $RESULT -eq 0 ]; then
        rm "$a"
    fi
done

le novità (da verificare) sono:

  • –vbr-new è stato rimosso, perchè di default con -V 0
  • -m j rimosso perchè impostato automaticamente con –vbr-new
  • -q 0 rimosso perchè di default con VBR
  • -s 44.1 rimosso perchè lame calcola automaticamente la frequenza di sampling

L’ output di lame in una prova è stato:

LAME 3.99.5 32bits (http://lame.sf.net)
CPU features: MMX (ASM used), SSE (ASM used), SSE2
polyphase lowpass filter disabled
Encoding <stdin> to xxxyyyzzz.mp3
Encoding as 44.1 kHz j-stereo MPEG-1 Layer III VBR(q=0)

Marketing Apple

apple_water_pageQuesta simpatica foto mostra come si può spacciare per iper-tecnologia qualsiasi cosa.

E’ esattamente quello che fa la Apple con i suoi mediocri prodotti: iPod iPhone iPad sono dei semplici dispositivi touch screen, con un microprocessore, una memoria di massa, e un sistema operativo.

E invece gli zombie che ne sono attratti pensano che siano una invenzione eccezionale, una cosa mai vista !

E non arrivano a capire la differenza tra l’ essere COSTRETTI a passare per iTunes per trasferire contenuti nei dispositivi, e la libertà di spostarli direttamente.
Tra l’ altro, iTunes è un software pachidermico che riempie l’ HD e il SO di cose inutili.ITunes gira solo sotto iOS e Windows, altra grandissima limitazione.

In sintesi: la Apple non è ciò che molti credono, è tantissimo fumo, scarso arrosto, e conto esorbitante.

Gli split non sono convenienti in molte installazioni

http://www.ingegneri.info/forum/viewtopic.php?f=9&t=20602

Il riscaldamento con split è molto efficace se la temperatura esterna non è troppo bassa. Considera che le pompe di calore sotto i 5°C cominciano a perdere rendimento in modo importante.
A -5°C il rendimento è decisamente basso, la macchina pompa poco calore, l’inquilino sente freddo, allora alza la temperatura sul telecomando dello split, allora l’inverter mette al massimo il compressore e i ventilatori dell’unità esterna e di quella interno, quindi aumenta al massimo il movimento dell’aria all’interno del locale. Così l’aria risulterà caldina vicino allo split e decisamente fredda lontano da questo. Il risultato è che magari stai fornendo la potenza di progetto al locale, ma il disconfort è tale da non farlo percepire.
Quindi lo split può essere una valida soluzione, ma in funzione della temperatura esterna di progetto, ti consiglio di verificare bene le rese termiche effettive alle temperature basse di ogni singola unità esterna. Le rese termiche dichiarate sono sempre ottimiste, ossia non considerano le perdite per distribuzione e, purtroppo le imprevedibili perdite per non buona installazione (coibente di scarsa qualità, troppe curve a gomito, lunghezza dei tubi…ecc.). Infatti i costruttori indicano che le rese dichiarate sono state ottenute in laboratorio con una determinata lunghezza dei tubi (tipicamente molto corta…).
Ti SCONSIGLIO l’installazione di un sistema del genere se la casa non è ben coibentata (tipo casa con muri di pietra senza isolamento). Le pareti faranno fatica a riscaldarsi e insieme al moto dell’aria, si crea un discomfort interno per gli occupanti, causato dallo scambio radiante con le pareti fredde insieme al moto dell’aria.
Tutto cambia se il fabbisogno dell’edificio è basso ed è quindi ben coibentato. Allora lo split, come qualsiasi altro sistema, avrà molto meno da lavorare e il risultato sarà un buon confort all’interno del locale.

Ti do la mia opinione sulle macchine che potresti utilizzare:
1) configurazioni con un monosplit per ogni stanza (COP e EER massimi, costi identici alle soluzioni multisplit, molto spazio occupato dalle unità esterne)
2) configurazioni multisplit (COP e EER di fortuna, specialmente nelle parzializzazioni più distanti… per capirsi un pentasplit da 9 kW con in funzione 1 solo split da 2 kW, rende davvero poco, costi di installazione identici a quelli del monospliti, poco spazio occupato dall’unità esterna)
3) una pompa di calore idronica tipo Altherma: hai praticamente una caldaia, con rendimenti medi stagionali elevatissimi, di buono è che può farti il riscaldamento degli ambienti, il raffrescamento e l’ACS. Il costo è sicuramente superiore alla soluzione con gli split, ma a mio avviso l’impianto è molto più efficiente e affidabile. I rendimenti medi stagionali, sono alti anche alle mie latitudini che hanno temperatura di progetto a -5°C. Ne ho installate diverse con pannelli radianti a pavimento per il riscaldamento, qualche split per il raffrescamento estivo e un buon impianto fotovoltaico sul tetto. Il cliente ha investito un po’, però è felice di essere autonomo energeticamente (casa nuova da 55 kWh/mq anno).

Infine, per esperienza…purtroppo anche domestica…se decidi di mettere split, evita soluzioni a parete o a soffitto per il riscadamento. Meglio optare soluzioni a pavimento, che nel funzionamento estivo rendono come quelle a parete, ma nel funzionamento invernale in riscaldamento, credimi che sono tutta un’altra musica!

gli split Mitsubishi garantiscono prestazioni di progetto fino a -10 °C prima di perdere in rendimento; se sei i una località umida in inverno, magari con nebbia, ti sconsiglio la PdC, perchè andrebbe in sbrinamento ogni 20 minuti fermando le unità interne con conseguente disconfort interno.
Le unità esterne mettile dal lato opposto del mare e che guardino verso l’interno, ben riparate dal vento che viene dal mare, altrimenti in 2 anni le batterie non le trovi più a causa della salsedine che le scioglie.
L’Altherma ha un difetto: ha una resistenza elettrica integrativa da 3 kW che ne abbassa il COP, io ho usato una SRP della Aermec ma il prezzo non è paragonabile anche perchè è un prodotto leggermente differente.

http://www.arredamento.it/articoli/articolo/riscaldamento/384/riscaldamento-e-convenienza-sistemi-a-confronto.html

Per riscaldare la propria casa, che si abiti nelle zone più calde d’Italia o in quelle dove l’inverno è particolarmente rigido, il sistema di riscaldamento più conveniente è quello a gas metano. Questa la conclusione a cui è giunta l’associazione indipendente Altroconsumo, che ha svolto un’indagine confrontando i vari sistemi di riscaldamento nelle diverse zone climatiche italiane, utilizzando alcune città campione quali Cuneo, Milano, Roma, Napoli, e pubblicando un intero dossier sul numero di ottobre della propria rivista.

Due le ipotesi di abitazione da riscaldare, considerate dalla ricerca: un trilocale di 90 mq, con due bagni e le tre stanze orientate a nord, ad un piano intermedio di una palazzina, ed una villa unifamilare di 140 mq a tre piani (il seminterrato occupato dal garage non riscaldato), con il soggiorno orientato a nord. Un discorso a parte va fatto nel caso di abitazioni situate nelle zone più calde del Paese, per le quali la forma di riscaldamento più adeguata consiste nell’utilizzo di stufe o condizionatori split, o ancora di apparecchi elettrici che riscaldino e rinfreschino la casa.

Per calcolare la convenienza dei vari sistemi Altroconsumo ha calcolato i costi annui fissi, per l’acquisto e l’installazione degli apparecchi e quelli di funzionamento, per la manutenzione ed il consumo di combustibile e di corrente elettrica per il riscaldamento e l’acqua calda. Ne è risultato che, da Palermo fino a Cuneo, per l’appartamento il gas metano è la soluzione più vantaggiosa (soprattutto se si tratta della tradizionale caldaia a camera stagna); lo segue il sistema alimentato da gpl a cisterna, la cui convenienza è proporzionale all’aumentare del freddo. Il gas metano conviene anche a chi vive in una villetta (in questo caso alle zone più freddde è consigliata la caldaia a condensazione). Il gas metano è tra i combustibili più diffusi in Italia; il suo impiego comporta solo l’installazione di una caldaia e l’allacciamento alla rete di distribuzione.

Per chi non dispone di un impianto di riscaldamento autonomo, ma centralizzato, le spese cambiano: ai costi fissi della manutenzione e del personale che ne controlla il funzionamento si aggiungono le spese che dipendono dal consumo di combustibile e dall’elettricità per il funzionamento dell’impianto. In molti condomini tali spese si suddividono tra gli inquilini in base a criteri che non tengono conto del consumo reale. Per evitare un’errata ripartizione dei costi, alcuni decidono per il riscaldamento autonomo, oppure possono essere installati contatori individuali nell’impianto centralizzato (obbligatori per gli edifici costruiti dopo 30 giugno 2000), applicabili ad ogni tipo di riscaldamento, tranne a quelli funzionanti a pannelli nel pavimento.

Il distacco del singolo dall’impianto di riscaldamento centralizzato, allo scopo di rendersi autonomo, dev’essere una scelta approvata dalla maggioranza dei condomini. E anche in questo caso, l’impianto resta in comune a tutti: quindi chi si è distaccato deve contribuire alle spese di conservazione della caldaia e del resto dell’impianto, oltre a pagare quelle di consumo del combustibile.