web-dev-qa-db-fra.com

Ruby: Comment faire une méthode statique publique?

En Java, je pourrais faire:

public static void doSomething();

Et puis, je peux accéder à la méthode de manière statique sans créer d'instance:

className.doSomething(); 

Comment puis-je faire cela en Ruby? C'est ma classe et d'après ce que j'ai compris, self. rend la méthode statique:

class Ask

  def self.make_permalink(phrase)
    phrase.strip.downcase.gsub! /\ +/, '-'
  end

end

Mais quand j'essaie d'appeler:

Ask.make_permalink("make a slug out of this line")

Je reçois:

undefined method `make_permalink' for Ask:Class

Pourquoi est-ce si je n'ai pas déclaré la méthode privée? 

55
Tom

Votre exemple donné fonctionne très bien

class Ask
  def self.make_permalink(phrase)
    phrase.strip.downcase.gsub! /\ +/, '-'
  end
end

Ask.make_permalink("make a slug out of this line")

J'ai essayé en 1.8.7 et aussi en 1.9.3 Avez-vous une faute de frappe dans votre script original?

Bonne chance

89
devanand

Il existe une autre syntaxe qui offre l'avantage de pouvoir ajouter plus de méthodes statiques

class TestClass

  # all methods in this block are static
  class << self
    def first_method
      # body omitted
    end

    def second_method_etc
      # body omitted
    end
  end

  # more typing because of the self. but much clear that the method is static
  def self.first_method
    # body omitted
  end

  def self.second_method_etc
    # body omitted
  end
end
15
Ivailo Bardarov

Voici mon copier/coller de votre code dans IRB. Semble bien fonctionner.

$ irb
1.8.7 :001 > class Ask
1.8.7 :002?>   
1.8.7 :003 >   def self.make_permalink(phrase)
1.8.7 :004?>     phrase.strip.downcase.gsub! /\ +/, '-'
1.8.7 :005?>   end
1.8.7 :006?>   
1.8.7 :007 > end
 => nil 
1.8.7 :008 > Ask.make_permalink("make a slug out of this line")
 => "make-a-slug-out-of-this-line"

Semble travailler. Testez-le également dans votre irb et voyez les résultats que vous obtenez. J'utilise 1.8.7 dans cet exemple, mais je l'ai également essayé dans une session Ruby 1.9.3 et cela a fonctionné de manière identique.

Utilisez-vous l'IRM comme votre implémentation Ruby (pas que je pense que cela devrait faire une différence dans ce cas)?

Dans irb, appelez Ask.public_methods et assurez-vous que le nom de votre méthode est dans la liste. Par exemple:

1.8.7 :008 > Ask.public_methods
 => [:make_permalink, :allocate, :new, :superclass, :freeze, :===, 
     ...etc, etc.] 

Étant donné que vous avez également marqué cette question comme étant une question Ruby-on-Rails, si vous souhaitez résoudre le modèle actuel dans votre application, vous pouvez bien sûr utiliser la console Rails: (bundle exec Rails c) et vérifier le caractère public de la méthode en question.

5
jefflunt

J'utilise Ruby 1.9.3 et le programme fonctionne bien dans mon irb.

1.9.3-p286 :001 > class Ask
1.9.3-p286 :002?>     def self.make_permalink(phrase)
1.9.3-p286 :003?>         phrase.strip.downcase.gsub! /\ +/, '-'
1.9.3-p286 :004?>       end
1.9.3-p286 :005?>   end
 => nil 
1.9.3-p286 :006 > Ask.make_permalink("make a slug out of this line")
 => "make-a-slug-out-of-this-line"

Cela fonctionne également dans mon script de test. Rien de mal avec votre code donné.Il va bien.

0
K M Rakibul Islam