web-dev-qa-db-fra.com

Appelez la méthode seulement si elle existe

Existe-t-il une magie cachée Ruby/Rails pour appeler une méthode uniquement si elle existe?

Disons que je veux appeler

resource.phone_number

mais je ne sais pas au préalable si la ressource répond à phone_number. Une façon de faire est

resource.phone_number if resource.respond_to? :phone_number

Ce n'est pas si beau si utilisé au mauvais endroit. Je suis curieux de savoir s'il existe quelque chose qui fonctionne plus dans le sens de l'utilisation de try (resource.try(:phone_number)).

53
Frans

Si vous n'êtes pas satisfait de la syntaxe standard Ruby, vous êtes libre de:

class Object
  def try_outside_Rails(meth, *args, &cb)
    self.send(meth.to_sym, *args, &cb) if self.respond_to?(meth.to_sym)
  end
end

À présent: 

resource.try_outside_Rails(:phone_number)

se comportera comme vous le souhaitiez.

34

Je voudrais essayer defined? ( http://Ruby-doc.org/docs/keywords/1.9/Object.html#defined-3F-method ). Il semble faire exactement ce que vous demandez:

resource.phone_number if defined? resource.phone_number
12
jmarceli

Je sais que c'est très vieux post. Mais je voulais juste savoir si cela pourrait être une réponse possible et si l'impact est le même.

resource.try(:phone_number) rescue nil

Merci

12
Bc91

À partir de Ruby 2.3.0 (qui est toujours à ce stade de la prévisualisation), vous pouvez utiliser le nouvel opérateur de navigation safe :

resource&.phone_number

De plus, si vous êtes intéressé par la syntaxe sélectionnée, je vous encourage à consulter la discussion sur feature request dans le système de suivi des problèmes de Ruby. J'ai aussi expliqué le raisonnement dans ma réponse ici .

6
Roope Hakulinen

Je ne peux pas parler pour l'efficacité, mais quelque chose comme ...

Klass.methods.include?(:method_name) 

travaille pour moi dans Rails 4

1
Stephen