Блоки и контекст в Ruby, или Что стоит за идентификатором в данном окружении::Журнал СА 1-2.2014
www.samag.ru
     
Поиск   
              
 www.samag.ru    Web  0 товаров , сумма 0 руб.
E-mail
Пароль  
 Запомнить меня
Регистрация | Забыли пароль?
О журнале
Журнал «БИТ»
Подписка
Где купить
Авторам
Рекламодателям
Магазин
Архив номеров
Вакансии
Контакты
   

ЭКСПЕРТНАЯ СЕССИЯ 2019


  Опросы

Какие курсы вы бы выбрали для себя?  

Очные
Онлайновые
Платные
Бесплатные
Я и так все знаю

 Читать далее...

1001 и 1 книга  
28.05.2019г.
Просмотров: 1296
Комментарии: 2
Анализ вредоносных программ

 Читать далее...

28.05.2019г.
Просмотров: 1407
Комментарии: 1
Микросервисы и контейнеры Docker

 Читать далее...

28.05.2019г.
Просмотров: 1083
Комментарии: 0
Django 2 в примерах

 Читать далее...

28.05.2019г.
Просмотров: 829
Комментарии: 0
Введение в анализ алгоритмов

 Читать далее...

27.03.2019г.
Просмотров: 1431
Комментарии: 0
Arduino Uno и Raspberry Pi 3: от схемотехники к интернету вещей

 Читать далее...

Друзья сайта  

Форум системных администраторов  

sysadmins.ru

 Блоки и контекст в Ruby, или Что стоит за идентификатором в данном окружении

Архив номеров / 2014 / Выпуск №1-2 (134-135) / Блоки и контекст в Ruby, или Что стоит за идентификатором в данном окружении

Рубрика: Разработка /  Особенности языка

Иван Шихалев ИВАН ШИХАЛЕВ, фрилансер, специализируется на веб-разработке и Ruby, shikhalev@gmail.com

Блоки и контекст в Ruby,
или Что стоит за идентификатором в данном окружении

Давайте разберемся с программным контекстом в Ruby: какие переменные и другие объекты доступны в конкретном месте программы, и как интерпретатор их ищет? Что обозначает конкретный идентификатор, откуда он берется? Почему отсюда, а не оттуда? И чему, наконец, в этом трижды перекинутом блоке будет равен self?

В программировании, неважно, на каком языке, есть такое понятие «контекст выполнения» – если мы не работаем исключительно с глобальными переменными, важно понимать, какие локальные объекты доступны и задействованы в каждой конкретной точке программы. Это достаточно просто для понимания, хотя и важно, в случае объектно-ориентированных языков, дизайн которых направлен на то, чтобы максимально изолироваться от глобального окружения и работать внутри одного объекта. И несколько сложнее, но еще более важно, в случаях, когда язык поддерживает замыкания – по сути, вынесение кода вместе с его контекстом в другое место.

На самом деле никакой особой магии (по крайней мере в случае Ruby) тут нет, и правила, определяющие работу с контекстом, довольно просты, а главное – логичны. Однако их надо знать и понимать очень четко, поскольку вариантов использования много, а кроме того, в языке есть способы переопределить поведение по умолчанию. Кроме того, блоки, образующие замыкания, в Ruby очень удобны и используются постоянно. При этом переменные не требуют отдельного объявления (подобного var в других языках), а определяются в момент инициализации – первого присваивания значения. Все это может привести к недопониманию и кажущейся неоднозначности.

Из чего состоит контекст?

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

В глобальном контексте, строго говоря, находятся только глобальные переменные – это те, имена которых начинаются с символа «$». Однако мы же можем обращаться к другим элементам – константам, методам, – находясь в глобальном окружении – непосредственно в тексте исходного файла вне всяких class и def? Можем, но только потому, что на самом деле находимся в неявном безымянном методе неявного объекта main. А «глобальные» константы и методы на самом деле принадлежат классу Object, к которому относится и main (поскольку от этого класса наследуются все остальные его элементы и доступны в любом контексте). Строго говоря, начиная с Ruby 1.9 это не совсем так – существует класс BasicObject, являющийся не наследником, а предком Object. Если мы для каких-то целей «унаследуемся» непосредственно от него, то внезапно обнаружим, что нам очень мало что доступно. Но так делать имеет смысл только в очень специфических задачах, на грани «хака».

Контекст объекта позволяет нам обращаться к его методам и константам класса без указания самого объекта, а также к его переменным экземпляра с префиксом «@» и переменным класса с «@@». Сам же текущий объект мы всегда можем получить посредством ключевого слова «self».

Наконец, локальный контекст – это все локальные переменные, заданные выше по тексту в рамках текущего метода.

Одна из особенностей Ruby – то, что принадлежность идентификатора тому или иному контексту, как правило, можно определить, не просматривая снизу вверх области видимости – глобальные переменные, переменные экземпляра и класса отличаются префиксами, имена констант всегда начинаются с большой буквы, а локальных переменных – с маленькой. Некоторую сумятицу вносят только методы – обладая именами, как у локальных переменных, они принадлежат контексту объекта. Тут действует простое правило: присваивание создает переменную и перекрывает имя метода. Тем не менее к нему по-прежнему можно обратиться посредством «self.(имя)». Стоит заметить, что присваивание всегда создает переменную, даже если у нас ранее определен атрибут, доступный для него. То есть в ситуации [1]:

class Alpha

attr_accessor :alpha

def beta

self.alpha = 1

alpha = 2

end

end

Атрибут после вызова beta будет равен единице, поскольку строчка без self к нему отношения не имеет.

Статью целиком читайте в журнале «Системный администратор», №1-2 за 2014 г. на страницах 111-115.


Комментарии отсутствуют

Добавить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

               Copyright © Системный администратор

Яндекс.Метрика
Tel.: (499) 277-12-41
Fax: (499) 277-12-45
E-mail: sa@samag.ru