obj2 = MyClass.new('abc','xyz')
Тогда можно сделать следующее:
$ irb -rfoo
irb(main):001:0> obj = MyClass.new(88,99)
=> #
Отметим, что хотя обращаться к сущностям, определенным в файле (например, к константе MyClass
) мы можем, это не относится к локальным переменным. Локальные переменные доступны только в самом файле, require
(выполненное хоть внутри, хоть вне irb
) доступа к ним не дает.
Новичков часто смущает информация, выводимая irb
:
$ irb -rfoo
irb(main):001:0> puts 'hello'
hello
=> nil
Позвольте, что тут делает nil
? Разумеется, это значение, возвращенное методом puts
.
Еще один источник недоразумений — метод eval
. Взгляните на следующий сеанс:
$ irb
irb (main) : 001:0> eval('var = 567')
=> 567
irb(main) :002:0> eval('var')
=> 567
irb(main):003:0> var
=> 567
Вас ничего не удивляет? Но давайте запустим следующий сценарий и посмотрим, что произойдет:
р eval('var = 567')
р eval('var')
р var
# Results:
# 567
# 567
# temp.rb:3: undefined local variable or method 'var' for main:Object
# (NameError)
У Ruby есть такая особенность: когда вы выполняете eval
, а вслед за ним еще один, они в некотором смысле разделяют «общую область видимости». Поэтому к переменной, определенной в первой строке, можно обратиться во второй (вне или внутри irb
). Но различие проявляется, когда мы попытаемся обратиться к той же переменной без использования eval
. В irb
это работает, а в сценарии мы получаем ошибку. Что происходит?
Поведение сценария следует считать более правильным. Не забывайте, что сама программа irb
написана на Ruby; здравый смысл подсказывает, что она, скорее всего, внутри вызывает eval
. Но мы только что убедились, что результат применения eval
может отличаться от того, что мы видим на верхнем уровне, поэтому исполнение кода внутри irb
не всегда идентично исполнению такого же кода в сценарии. Об этом не следует забывать, особенно если вы ставите какие-нибудь экзотические эксперименты.
Имейте в виду, что irb
настраивается в широких пределах. При запуске она читает все инициализационные файлы, которые может найти, в следующем порядке:
• файл ~/.irbrc
;
• файл .irbrc
;
• файл irb.rс
;
• файл _irbrc
;
• путь, указанный в переменной окружения $irbrc
.
Инициализационные файлы пишутся на Ruby. В них можно настраивать текст приглашения и многое другое. Подробно эти файлы обсуждаются в книге «Programming Ruby». Ниже мы сделаем лишь несколько замечаний.
Если ваша версия Ruby собрана с поддержкой библиотеки GNU readline (обычно так и есть), то вы можете перемещаться по истории команд с помощью клавиш со стрелками вверх и вниз. Еще важнее, что работает механизм завершения по клавише Tab: когда вы набираете начало идентификатора, а затем нажимаете Tab, irb
пытается дописать имя идентификатора за вас.
Чтобы включить механизм завершения, добавьте в файл .irbrc
следующий фрагмент:
IRB.conf[:AUTO_INDENT] = true
IRB.сonf[:USE_READLINE] = true
IRB.conf[:LOAD_MODULES] ||= []
IRB.conf[:LOAD_MODULES] |= ['irb/completion']
В файле .irbrc
может содержаться произвольный код. Например, я часто пользуюсь описанным ниже методом. Для краткости он назван sm
(сокращение от «show methods»), а цель — вывести (в алфавитном порядке) список всех методов, которые можно вызывать для данного объекта, за исключением тех, которые он унаследовал от своих предков:
def sm(obj)
list = obj.methods
anc = obj.class.ancestors — [obj.class]
anc.each {|a| list -= a.instance_methods }
list.sort
end
Вот пример его использования:
irb(main):001:0> str = 'hello'
=> 'hello'
irb(main):002:0> sm str
=> ['%', '*', '+', '<<', '<=>', '[]', '[]=', 'capitalize',
'capitalize!', 'casecmp', 'center', 'chomp', 'chomp!', 'chop', 'chop!',
'concat', 'count', 'crypt', 'delete', 'delete!', 'downcase', 'downcase!',
'dump', 'each', 'each_byte', 'each_line', 'empty?', 'gsub', 'gsub!', 'hex',
'index', 'insert', 'intern', 'length', 'ljust', 'lstrip', 'lstrip!', 'match',
'next', 'next!', 'oct', 'replace', 'reverse', 'reverse!', 'rindex', 'rjust',
'rstrip', 'rstrip!', 'scan', 'size', 'slice', 'slice!', 'split', 'squeeze',
'squeeze!', 'strip', 'strip!', 'sub', 'sub!', 'succ', 'succ!', 'sum',
'swapcase', 'swapcase!', 'to_f', 'to_i', 'to_str', 'to_sym', 'tr', 'tr!',
'tr_s', 'tr_s!', 'unpack', 'upcase', 'upcase!', 'upto']
irb(main):003:0> sm String
=> ['allocate', 'new', 'superclass']
irb(main):004:0> sm 123 => ['%', '*', '**', '+', '-', '/', '<<', '>>', '[]', '^',
'id2name', 'power!', 'rdiv', 'rpower', 'size', 'to_f', 'to_sym, '|', '-']
Программа irb
позволяет запускать подсеансы внутри сеанса, хотя это используется и нечасто. Можно запустить несколько сеансов и переключаться между ними, у каждого сеанса собственный набор привязок.