Question

J'ai besoin d'une fonction qui prend le nom d'un symbole sous forme de chaîne et indique si ce symbole est déjà défini. La fonction ValueQ est fermée mais renvoie False pour les noms de fonction. En outre, il faut des symboles plutôt que des chaînes.

Exemples:

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)

PS: Merci à Pillsy pour avoir souligné la nécessité de vérifier les valeurs à la baisse et les sous-valeurs.

Était-ce utile?

La solution 2

Je l'ai bricolé, ce qui semble fonctionner:

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

J'espère qu'il existe une solution plus jolie.

PS: Merci à Pillsy pour avoir souligné la nécessité de vérifier les valeurs à la baisse et les sous-valeurs.

Autres conseils

Je pense que les noms devraient faire l'affaire:

  

Noms [" chaîne "] donne une liste des   noms des symboles qui correspondent à la   chaîne.

Si Names [" foo "] renvoie {}, il ne devrait pas y avoir de définition pour" foo ", sinon il devrait renvoyer {" foo &}}. Donc, votre fonction 'définie' peut être réalisée comme suit:

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

Pour les symboles au moins, car cela ne fonctionne pas pour "7", car 7 n'est pas un symbole. Vous pouvez gérer ce cas séparément, par exemple avec NumberQ.

Vous pouvez également utiliser Symbole pour créer un symbole à partir d'une chaîne (utile pour générer automatiquement des symboles) et Définition pour vérifier les définitions d'un symbole.

  

Le symbole ["nom"] fait référence à un symbole avec   le nom spécifié.

     

Définition [symbole] s'imprime en tant que   définitions données pour un symbole.

MODIFIER : mieux que de rechercher les noms renvoyés, NameQ [" nom "] vous indique si un nom existe. Vous ne savez toujours pas si le symbole a une définition explicite, c'est juste qu'il a été mentionné.

Vous pouvez utiliser DownValues ?? pour voir si vous avez des "fonctions". associé à un symbole. Cela fonctionnera pour des définitions comme

f[x_, y_] := x + y

ou

g[3] = 72 * a;

Cela ne fonctionnera pas pour des choses exotiques comme

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

mais la plupart des gens ne penseront pas que cela définisse une fonction de toute façon. Si vous voulez vérifier l'existence d'une définition de fonction, vous devez convertir le nom en une expression (et assurez-vous qu'elle est encapsulée dans Hold quand vous le ferez!). Voici une fonction raisonnablement robuste qui vérifie à la fois DownValues ?? et SubValues ??:

functionNameQ[name_String] := 
    With[{ hSymbol = ToExpression[name, InputForm, Hold] },
        MatchQ[hSymbol, Hold[_Symbol]] &&
            ((DownValues @@ hName) =!= {} || (SubValues @@ hName) =!= {})];
defined[str_] := Not[ToString[FullDefinition[str]] === ""]
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top