Pregunta

Necesito una función que tome el nombre de un símbolo como una cadena y devuelva si ese símbolo ya está definido. La función ValueQ está cerca pero devuelve False para los nombres de función. Además, toma símbolos en lugar de cadenas.

Ejemplos:

defined["N"] --> True (predefined function N)
defined["x"] --> False
x = 7;
defined["x"] --> True (x is now defined)
defined["7"] --> True (7 is a number)
f[x_] := 2x
defined["f"] --> True (f has DownValues)
g[x_][y_] := x+y
defined["g"] --> True (g has SubValues)

PD: Gracias a Pillsy por señalar la necesidad de verificar tanto los DownValues ??como los SubValues.

¿Fue útil?

Solución 2

Lo combiné, lo que parece funcionar:

defined[s_] := ToExpression["ValueQ[" <> s <> "]"] || 
               Head@ToExpression[s] =!= Symbol || 
               ToExpression["Attributes[" <> s <> "]"] =!= {} ||
               ToExpression["DownValues[" <> s <> "]"] =!= {} ||
               ToExpression["SubValues[" <> s <> "]"] =!= {}

Esperemos que haya una solución más bonita.

PD: Gracias a Pillsy por señalar la necesidad de verificar tanto los DownValues ??como los SubValues.

Otros consejos

Creo que los nombres deberían hacer el truco:

  

Nombres [" string "] proporciona una lista de   nombres de símbolos que coinciden con   cadena.

Si Nombres [" foo "] devuelve {}, entonces no debería haber definiciones para foo; de lo contrario, debería devolver {" foo "}. Por lo tanto, su función 'definida' podría hacerse como:

defined[str_] := Names[str] != {}

Para símbolos al menos, porque esto no funciona para '' 7 '', ya que 7 no es un símbolo. Podría manejar este caso por separado, por ejemplo con NumberQ.

Además, puede usar Símbolo para hacer un símbolo de una cadena (útil para generar símbolos automáticamente) y Definición para verificar las definiciones de un símbolo.

  

El símbolo [" nombre "] se refiere a un símbolo con   el nombre especificado.

     

Definición [símbolo] se imprime como   definiciones dadas para un símbolo.

EDITAR : Mejor que mirar lo que Nombres devuelve, NameQ [" name "] le dice si existe un nombre dado. Sin embargo, aún no le dice si el símbolo tiene una definición explícita, solo que ha sido mencionado.

Puede usar DownValues ?? para ver si tiene " funciones " asociado con un símbolo. Esto funcionará para definiciones como

f[x_, y_] := x + y

o

g[3] = 72 * a;

No funcionará para cosas exóticas como

h[a_][b] = "gribble";

pero la mayoría de la gente no pensará que eso define una función de todos modos. Si desea verificar la existencia de una definición de función, debe convertir el nombre en una expresión (y asegurarse de que esté envuelto en Hold cuando lo haga). Aquí hay una función razonablemente robusta que verifica tanto DownValues ?? como SubValues ??:

functionNameQ[name_String] := 
    With[{ hSymbol = ToExpression[name, InputForm, Hold] },
        MatchQ[hSymbol, Hold[_Symbol]] &&
            ((DownValues @@ hName) =!= {} || (SubValues @@ hName) =!= {})];
defined[str_] := Not[ToString[FullDefinition[str]] === ""]
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top