ruby -- 全局和局部问题
黄舟
黄舟 2017-04-22 08:59:49
0
6
776
n = 5
def num
  puts n
end

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

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

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

黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

répondre à tous(6)
黄舟

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
大家讲道理
@n = 5
def num
    puts @n
end

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

迷茫

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.
伊谢尔伦

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
巴扎黑

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.

小葫芦

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.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal