2010-05-28 21 views
0

Il me semble assez commun d'avoir un argument, dans un langage dynamiquement typé qui est soit un objet soit une clé pour rechercher cet objet. Par exemple, quand je travaille avec une base de données que je pourrais avoir une méthode getMyRelatedStuff (personne)Existe-t-il une syntaxe pour cela? Dans n'importe quelle langue?

Tout ce que je vraiment besoin de rechercher les choses qui s'y rapporte est l'identifiant de la personne ainsi ma méthode pourrait ressembler à ceci en python:

def getMyRelatedStuff(person_or_id): 
    id = person_or_id.id if isinstance(person,User) else person_or_id 
    #do some lookup 

Ou aller dans l'autre direction:

def someFileStuff(file_or_name): 
    file = file_or_name if hasattr(file,'write') else open(file_or_name) 

EDIT: Je cherche construit dans la syntaxe pour cela, le plus proche, je peux penser est des mots-clés implicites et explicites en C# qui vous permettent de définir un cast entre les types.

+0

Vous ne posez pas vraiment de question. Qu'est-ce que vous voulez savoir? –

+0

@Nick C'est dans le titre –

+0

Vous voulez dire que vous cherchez une sorte de syntaxe intégrée pour cela? –

Répondre

8

j'étudie les langages de programmation pour gagner leur vie. Je n'ai jamais vu un langage avec une syntaxe intégrée pour cette opération. Je ne suis même pas sûr de ce que vous voulez qu'une telle syntaxe ressemble, d'autant plus que vous pouvez définir une fonction pour l'un de ces modèles.

Les gens qui aiment la syntaxe extensible ont tendance à définir des macros Lisp :-)

+0

Je ne suis pas tout à fait sûr que c'est tout à fait vrai (Vous êtes l'expert et je ne veux pas manquer de respect, mais écoutez-moi). C++ a la (condition)? (Exécution en cours) :(execute on fail); syntaxe. Alors peut-être, c'est à quoi fait référence @Michael?) – inspectorG4dget

+0

Python a aussi un opérateur ternaire et il est même utilisé dans la question. – wRAR

+0

J'ai vraiment besoin d'apprendre Lisp! Et je veux votre travail :) – Michael

1

Vous pouvez le faire dans n'importe quelle langue qui ne vérifie pas le type de paramètres de la fonction lors de la compilation.

JavaScript:

function doSomething(person) 
{ 
    var name; 
    if(typeof(person) == "string") 
    name = person; 
    else 
    name = person.name; 
    //you can simplify it to 
    name = (typeof(person) == "string") ? name : person.name; 
} 
3

Vous cherchez function overloading? Par exemple:

doSomething(Person p); 
// these could do lookup and dispatch to doSomething(Person p)... 
doSomething(String personName); 
doSomething(Integer personId); 

Tout OO langage fortement typé devrait être en mesure de le faire.

Pour les langages typés dynamiquement, je ne connais pas d'autre moyen que de faire manuellement un type d'opération de type check (instanceof), et cette méthode peut être très mauvaise. Vous êtes mieux de faire tout ce que nous avons fait avant POO: utiliser les fonctions nommés différemment, par exemple:

doSomethingByName(personName); 
doSomethingById(personId); 

Si votre code est bien structuré autrement, la plupart de ces « double » des fonctions sera assez faible. Schéma, LISP, ou à peu près n'importe quelle langue avec des macro.

1

Je n'ai jamais vu intégré syntaxe pour cela dans toutes les langues que j'ai utilisées.

Notez que dans Python ceci est généralement géré par des exceptions:

def getMyRelatedStuff(person_or_id): 
    "The verbose way" 
    try: 
     my_id= person_or_id.id 
    except AttributeError: 
     my_id= person_or_id 

, mais de préférence:

def getMyRelatedStuff(person_or_id): 
    "The terse way" 
    my_id= getattr(person_or_id, "id", person_or_id) 

et comme pour someFileStuff:

def someFileStuff(file_or_name): 
    try: 
     fobj= open(file_or_name) 
    except TypeError: 
     fobj= file_or_name 

Essayez d'éviter d'utiliser intégré dans des noms comme id et file dans votre co de; ils introduisent des bugs subtils dans vos programmes.

0

Lisp

Cela peut facilement être mis en œuvre à l'aide de macros Lisp:

(defmacro get-if-not [func val alt] 
    `(if (~func ~val) 
    ~val 
    ~alt)) 

Vous pouvez utiliser cette expression comme ceci:

(get-if-not file? file_or_name (open file_or_name)) 

qui étendra à:

(if (file? file_or_name) file_or_name (open file_or_name)) 

Les macros sont incroyables. Personnellement, je refuse d'utiliser une langue qui ne les a pas.