Pregunta

I han reducido a un pequeño ejemplo un código que tengo, que las pruebas de si una variable llamada class-name tiene un valor asignado a él:

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"

El value? 'class-name expresión devuelve falsa aquí. Por otro lado, si completo en la rama que falta con una misión:

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"

Esto devolverá cierto para value? 'class-name. Sin embargo, en este segundo caso, se class-name: default-class-name ni siquiera ejecutado todavía.

Me gustaría pensar que la clase-nombre no debe existir en la memoria, por lo value? 'class-name debe devolver false. ¿Por qué está volviendo value? cierto lugar?

¿Fue útil?

Solución

Está utilizando function. Este escanea el cuerpo de la función y pre-crea las variables locales para que, inicializados a NINGUNO. Es por eso que value? 'class-name llega a ser verdad (porque ninguno es un valor legal de una variable, distinta de la situación de estar "preparada").

Si ha utilizado func lugar, a continuación, ambos se devuelve falso.

Otros consejos

No creo que se comporta de manera diferente que function func /local. Vistazo a estos ejemplos:

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

que no le dan ningún valor a x, pero dice que tiene un valor. Lo mismo para / local

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

Debido al realizar una variable local (o un refinamiento), entonces significa que ya ha configurado un valor para ella (que no es) y que es lo que hace function.

Aquí os muestro dos ejemplos no usar la función, pero por lo demás equivalentes a su código:

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
    ][
    ]
]

Mientras que la función value? en el primer ejemplo rendimientos #[false], en el segundo ejemplo se produce #[true]. Esto es debido a que los "argumentos de refinamiento" después de un "refinamiento sin usar" (un refinamiento que no se utiliza en la llamada real) se inicializan a #[none!] junto con la variable de refinamiento. Esto se aplica a las variables /local también, puesto que el refinamiento /local no difiere de otros refinamientos de función (excepto por el hecho, que es una convención para utilizarlo para definir variables locales).

Desde el generador function utiliza el método /local para implementar las variables locales "bajo el capó", la descripción anterior se aplica a todas las funciones que genera también.

Hay otra manera, lo que evita el uso de FUNC / LOCAL y todavía permite el uso de FUNCTION.

Eso es no utilizar un conjunto-PALABRA! para la asignación. En lugar de utilizar la función SET en un LIT-PALABRA!

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
    ]
]

obtendrá #[false] para la función value?. Sin embargo, la llamada al conjunto será el establecimiento de class-name en el entorno global ... no como un local.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top