2013-02-23 4 views
5

Я изучаю Ruby и Python одновременно, и одна из вещей, которые я заметила, заключается в том, что эти 2 языка, похоже, рассматривают область действия по-разному. Вот пример того, что я имею в виду:Область применения Ruby и Python

# Python 
a = 5 
def myfunc(): 
    print a 

myfunc() # => Successfully prints 5 

# Ruby 
a = 5 
def myfunc 
    puts a 
end 

myfunC# => Throws a "NameError: undefined local variable or method `a' for main:Object" 

Оказывается, что Защита блок может получить доступ к переменному, объявленным вне непосредственной сферы в Python, но не в Ruby. Может ли кто-нибудь подтвердить правильность моего понимания? И если да, то является ли один из этих способов мышления масштаба более распространенным в программировании?

+0

Для стороны Python вы правы (очевидно, что вам нужно больше внимания, но ваша формулировка не противоречит ни одному из них). – delnan

+0

Возможный ответ Python здесь: http://stackoverflow.com/questions/370357/python-variable-scope-question –

ответ

4

Отказ от ответственности: Я не являюсь экспертом Python

В питона, где переменные, определенные в модуле, по умолчанию, переменных модуля, и как таковой глобальный к этому модулю. В Ruby, когда вы определяете строчную переменную, она всегда является локальной переменной. Локальные переменные доступны только в блоке, который их определял, и в procs/lambdas, определенном в этом блоке, который обертывает переменную.

В Ruby, для переменных, чтобы пересечь области, она должна быть либо:

  • Константа (ALL_CAPS): Всегда доступна, если префикс с правой рамкой
  • переменной классы (@@double_at): Всегда доступен из определяющего класса и любых подклассов, но не извне
  • Переменная экземпляра (@single_at): Доступна только изнутри этого объекта и извне с методами геттера/get_instance_variable.
  • Global ($starts_with_dollar): Плохая идея. Пересекается по всем областям, без необходимости определения области видимости. Не используй!
+0

А я вижу, поэтому для Python, когда вы определяете переменную вне любого класса или блока, по умолчанию она будет в глобальной области. Это контрастирует с Ruby, где Ruby рассматривает каждую область как свою отдельную сущность, и вы определяете глобальные переменные, доступные во всех областях с помощью $. Это точное резюме? – wmock

+0

@WillsonMock: В значительной степени. – Linuxios

+2

Незначительные nitpick: константы не ALL_CAPS, они просто начинаются с заглавной буквы. Классные имена, например, являются константами. – steenslag

1

В Ruby, если вы хотите получить доступ к переменной, определенной вне метода, который вы вызываете, вам необходимо определить его как глобальный. Ruby попытается сопоставить переменную, определенную в локальной области, если она не находит ее, генерирует исключение.

Вы можете определить глобальную переменную с знаком $.

$a = 5 
def myfunc 
    puts $a 
end 

myfunc 

Однако, как правило, не является хорошей практикой для определения глобальных переменных, иначе это может привести к загрязнению глобального пространства имен.

+3

Это просто неправильно. Переменная экземпляра ('@ a') достаточно. – steenslag

1

Вы можете использовать модуль dis, чтобы узнать, что делает Python.

import dis 

a = 5 
def myfunc(): 
    print a 

Результат:

>>> dis.dis(myfunc) 
15   0 LOAD_GLOBAL    0 (a) 
       3 PRINT_ITEM   
       4 PRINT_NEWLINE  
       5 LOAD_CONST    0 (None) 
       8 RETURN_VALUE 

Таким образом, вы можете видеть, что a находится в глобальном масштабе.

Смежные вопросы