100 votes

Est-il possible de disposer de Méthodes à l'intérieur de Méthodes?

J'ai une méthode à l'intérieur d'une méthode. L'intérieur de la méthode dépend d'une variable de boucle en cours d'exécution. Est-ce une mauvaise idée?

179voto

Jörg W Mittag Points 153275

Non, Ruby n'a pas imbriquée méthodes.

Vous pouvez faire quelque chose comme ceci:

class Test1
  def meth1
    def meth2
      puts "Yay"
    end
    meth2
  end
end

Test1.new.meth1

Mais c'est pas une méthode imbriquée. Je le répète: Ruby n'a pas imbriquée méthodes.

C'est une dynamique de la méthode de définition. Lorsque vous exécutez meth1, le corps de l' meth1 sera exécuté. Le corps arrive juste à définir une méthode nommée meth2, c'est pourquoi après l'exécution de l' meth1 une fois, vous pouvez appeler meth2.

Mais où est - meth2 ? Eh bien, ce n'est évidemment pas définie comme une méthode imbriquée, puisqu'il n'y sont pas imbriqués méthodes en Ruby. Il est défini comme une méthode d'instance de Test1:

Test1.new.meth2
# Yay

Aussi, il sera bien évidemment être redéfinis chaque fois que vous exécutez meth1:

Test1.new.meth1
# Yay

Test1.new.meth1.
# test1.rb:3: warning: method redefined; discarding old meth2
# test1.rb:3: warning: previous definition of meth2 was here
# Yay

En bref: non, Ruby n'a pas de soutien imbriquée méthodes.

Notons également que, dans le Rubis, le corps de méthode ne peut pas être fermetures, bloque uniquement les organes. Ce joli beaucoup élimine les principaux cas d'utilisation de imbriquée méthodes, car même si Ruby pris en charge imbriquée méthodes, vous ne pouviez pas utiliser à l'extérieur de la méthode des variables dans la méthode imbriquée.

5voto

iirekm Points 2338

Non, non, Ruby n'ont imbriquées méthodes. Vérifiez ceci:

def outer_method(arg)
    outer_variable = "y"
    inner_method = lambda {
      puts arg
      puts outer_variable
    }
    inner_method[]
end

outer_method "x" # prints "x", "y"

2voto

mdmoskwa Points 73

Vous pouvez faire quelque chose comme ceci

module Methods
  define_method :outer do 
    outer_var = 1
    define_method :inner do
      puts "defining inner"
      inner_var = outer_var +1
    end
    outer_var
  end
  extend self
end

Methods.outer 
#=> defining inner
#=> 1
Methods.inner 
#=> 2

Ceci est utile lorsque vous êtes en train de faire des choses comme écrire des DSLs qui nécessitent le partage de la portée entre les méthodes. Mais sinon, vous êtes beaucoup mieux de faire autre chose, parce que les autres réponses, a déclaré, inner est redéfinie à chaque fois qu' outer est invoquée. Si vous voulez que ce comportement, et vous pourrait parfois, c'est un bon moyen pour l'obtenir.

-3voto

bbozo Points 2090

:-D

Ruby a imbriquées méthodes, seulement ils ne font pas ce que vous attendez pour

1.9.3p484 :001 > def kme; 'kme'; def foo; 'foo'; end; end              
 => nil 
1.9.3p484 :003 >   self.methods.include? :kme
 => true 
1.9.3p484 :004 > self.methods.include? :foo
 => false 
1.9.3p484 :005 > kme
 => nil 
1.9.3p484 :006 > self.methods.include? :foo
 => true 
1.9.3p484 :007 > foo
 => "foo" 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X