Maison  >  Questions et réponses  >  le corps du texte

ruby -- 全局和局部问题

n = 5
def num
  puts n
end

为什么是错的的?
我知道全局和局部基本原理。
局部变量在函数里只能使用,在外部是不存在。

但是在python或js里使用这样方式可以执行的!
还是只有ruby要在函数使用变量需要重新宣告。

请问各位可以解释吗?
谢谢

黄舟黄舟2712 Il y a quelques jours717

répondre à tous(6)je répondrai

  • 黄舟

    黄舟2017-04-22 09:01:49

    def ouvre un nouveau périmètre

    n = 5
    local_variables       # => [:n, :_]
    def num
      local_variables     # => []
    end
    

    Si vous souhaitez accéder à n, vous devez utiliser la portée d'aplatissement

    define_method :num do
        puts n
    end
    

    répondre
    0
  • 大家讲道理

    大家讲道理2017-04-22 09:01:49

    @n = 5
    def num
        puts @n
    end
    

    Je suis aussi un débutant, voyons ce que disent les autres experts.

    répondre
    0
  • 迷茫

    迷茫2017-04-22 09:01:49

    Mais il peut être exécuté de cette manière en python ou en js !

    Lecture seule en Python


    Ce qui suit est une hypothèse quant à la raison pour laquelle Ruby a fait cela ?

    Dans Ruby, def les méthodes générées ne peuvent accéder qu'aux variables globales. La méthode générée par
    define_method et le proc généré par -> (param) {} ou lambda { |param| } ont des fermetures et peuvent accéder aux variables externes.

    Je suppose que c'est parce que Ruby pense que la situation la plus courante est que vous n'avez pas besoin d'accéder aux variables externes, donc def ne vous donne pas accès. Cela a l'avantage :

    .
    • Ne jouera pas avec les variables externes involontairement comme js. Afin d'éviter cela en JavaScript, toutes les variables utilisées dans le corps doivent être indéfinies dans l'en-tête function, qui est très verbeux.
    • Pas besoin de créer des fermetures, ce qui permet d'économiser des frais généraux.

    Quant aux lambdas avec fermetures, c'est normal. Est-il acceptable d'utiliser des lambdas sans fermetures ?

    Quant à define_method, je suppose que c'est à cause de

    • define_method Parce qu'il s'agit de ce qu'on appelle la métaprogrammation, il y a plus de chances d'utiliser des variables externes. (À l'origine, utiliser la métaprogrammation signifie être paresseux et taper moins. Si vous ne pouvez pas utiliser de variables externes et devez les transmettre en tant que paramètres, ce sera épuisant.) Donc.
    • Il est parfois gênant que la
    • définition de la méthode ne puisse pas contenir de fermetures, mais ce n'est généralement pas nécessaire, alors laissez la define_method plus longue contenir des fermetures.
    • define_method En plus de define_method (symbol) { |param| }, il peut également être écrit comme define_method(symbol, method) Parmi eux, method est plus couramment utilisé pour passer un lambda puisque lambda est transmis, si define_method lui-même n'en a pas. une fermeture, ce sera très incohérent Dit, alors laissez-vous prendre.

    répondre
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-22 09:01:49

    Ce que @Andrew_375683 a dit est correct.
    Principalement une question de portée
    Mais voici un moyen simple de le résoudre. Transformez simplement n en fonction

    .
    def n
      5
    end
    
    def num
      p n
    end
    
    num
    

    répondre
    0
  • 巴扎黑

    巴扎黑2017-04-22 09:01:49

    C’est une question brûlante. J'y suis juste allé et quelques personnes m'ont répondu à mon retour.

    Vous pensez que le n dans votre code est une variable globale, mais malheureusement ce n'est pas le cas

    irb(main):006:0> x =10
    => 10
    irb(main):009:0> defined? x
    => "local-variable"
    

    Si vous devez le modifier, ajoutez simplement $ comme préfixe :

    irb(main):010:0> $x = 1
    => 1
    irb(main):011:0> defined? $x
    => "global-variable"
    

    Dans le magnifique style rubis, $ est tellement accrocheur. Le patron de Ruby sait que les variables globales sont indispensables, mais il a aussi peur des abus, alors il joue un petit tour ;). Cela implique la connaissance de la portée des variables Ruby. Les avantages du Ruby sont complexes et uniques.

    @andrewzhyl l'a bien dit, j'aime ça.

    répondre
    0
  • 高洛峰

    高洛峰2017-04-22 09:01:49

    A noter : La différence entre def et def_method : def est le mot clé utilisé pour définir une méthode ; def_method est une méthode, sa fonction est de générer une nouvelle méthode, le code dans def est complètement isolé du contexte (uniquement le code avec @Variables avec Meida); et definition_method est plus ouvert, et je suis prêt à rencontrer des amis sans aucune modification.

    répondre
    0
  • Annulerrépondre