Domanda

Ho ridotto fino a un piccolo esempio un codice che ho, che test per se una variabile denominata class-name ha un valore assegnato:

ask-params: function [
    config-file [file!]
    default-class-name
    default-fields
] [
    probe value? 'class-name
    input
    either (value? 'class-name) [
        probe class-name
    ] [
        ;-- omit code in this branch for now
    ]
]

ret-block: ask-params %simple-class.params.txt "Person" "First Name, Last Name"

Il value? 'class-name espressione restituisce falsa qui. D'altra parte, se io riempio nel ramo mancante con un incarico:

ask-params: function [
    config-file [file!]
    default-class-name
    default-fields
] [
    probe value? 'class-name
    input
    either (value? 'class-name) [
        probe class-name
    ] [
        class-name: default-class-name
    ]
]

ret-block: ask-params %simple-class.params.txt "Person" "First Name, Last Name"

Ciò restituirà vero per value? 'class-name. Ma in questo secondo caso, class-name: default-class-name non è nemmeno ancora eseguito.

Vorrei pensare che class-name non dovrebbe esistere in memoria, in modo da value? 'class-name deve essere restituito false. Perché value? tornando vero invece?

È stato utile?

Soluzione

Si utilizza function. Questo esegue la scansione del corpo della funzione e pre-crea le variabili locali per voi, inizializzati a NESSUNO. Ecco perché value? 'class-name diventa vero (perché nessuno è un valore legale di una variabile, distinta dalla situazione di essere "unset").

Se si è utilizzato func invece, poi entrambi avrebbero return false.

Altri suggerimenti

Non credo che si comporta in modo diverso rispetto function func /local. Guardate questi esempi:

>> f: func [/x] [value? 'x]
>> f
== true

I non ha dato alcun valore per x, ma dice che ha un valore. Lo stesso vale per / local

>> f: func [/local x] [value? 'x]
>> f
== true

Perché quando si effettua un locale (o un perfezionamento) variabile, allora vuol dire che già impostato un valore per esso (che non è) e che è quello che fa function.

Qui vi mostro due esempi non si utilizza la funzione, ma per il resto equivalente al codice:

ask-params: func [config-file [file!] default-class-name default-fields] [
    probe value? 'class-name
    input
    either (value? 'class-name) [
        probe class-name
    ][
    ]
]

ask-params: func [
    config-file [file!] default-class-name default-fields /local class-name
] [
    probe value? 'class-name
    input
    either (value? 'class-name) [
        probe class-name
    ][
    ]
]

Mentre la funzione value? nel primo esempio rese #[false], nel secondo esempio produce #[true]. Questo perché gli "argomenti restringimento" a seguito di un "perfezionamento inutilizzato" (un perfezionamento che non viene utilizzato nella chiamata attuale) vengono inizializzati a #[none!] insieme con la variabile raffinatezza. Questo vale per le variabili /local pure, poiché la raffinatezza /local non differisce da altri filtri funzione (tranne per il fatto, che è una convenzione di usarlo per definire variabili locali).

Poiché il generatore function utilizza il metodo /local per implementare variabili locali "sotto il cofano", la descrizione di cui sopra si applica a tutte le funzioni che genera pure.

C'è un altro modo, che evita con il tasto FUNC / LOCAL e consente comunque l'uso della funzione.

Questo è di non usare un set-PAROLA! per l'assegnazione. Utilizzare invece la funzione SET su un LIT-parola!

ask-params: function [config-file [file!] default-class-name default-fields] [
    probe value? 'class-name
    input
    either (value? 'class-name) [
        probe class-name
    ] [
        set 'class-name default-class-name
    ]
]

Si otterrà #[false] per la funzione value?. Tuttavia, la chiamata a SET sarà l'impostazione class-name nel contesto globale ... non come un locale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top