Программирование на языке Ruby
Шрифт:
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
позволяет запускать подсеансы внутри сеанса, хотя это используется и нечасто. Можно запустить несколько сеансов и переключаться между ними, у каждого сеанса собственный набор привязок. Может быть, вам это и не кажется полезным, но можно, например, задать объект в сочетании с подкомандой
irb
. Тогда контекстом подсеанса станет этот объект, псевдопеременная self
будет ссылаться на него, он же станет областью видимости и т.д.:
$ irb
irb(main):001:0> t0 = Time.now
=> Mon Jul 31 04:51:50 CDT 2006
irb(main):002:0> irb t0
irb#1(Mon Jul 31 04:51:50 CDT 2006):001:0> strftime("%a %b %c")
=> "Mon Jul Mon Jul 31 04:51:50 2006"
irb#1(Mon Jul 31 04:51:50 CDT 2006):002:0> to_i
=> 1154339510
irb#1(Mon Jul 31 04:51:50 CDT 2006):003:0> self + 1000
=> Mon Jul 31 05:08:30 CDT 2006
irb#1(Mon Jul 31 04:51:50 CDT 2006):004:0> wday
=> 1
irb#1(Mon Jul 31 04:51:50 CDT 2006):005:0> class
SyntaxError: compile error
(irb#1):5: syntax error, unexpected $end
from (irb#1):5
irb#1(Mon Jul 31 04:51:50 CDT 2006):006:0> self.class
=> Time
irb#1(Mon Jul 31 04:51:50 CDT 2006):007:0> quit
=> #<IRB::Irb: @scanner=#<RubyLex:0xb7ee8394>,
@signal_status=:IN_EVAL, @context=#<IRB::Context:0xb7ee86f0>>
irb(main):003:0> quit
$
Мы
уже убедились в полезности библиотекиruby-breakpoint
(см. главу 16). В сочетании с ней irb
становится мощным средством отладки, поскольку вы можете установить точку прерывания и «оказаться» в сеансе irb
. Конечно, это не настоящий отладчик, потому что не позволяет исполнять код в пошаговом режиме. Иногда бывает полезна библиотека
xmp
. Она принимает предложения на Ruby, исполняет их и помещает возвращаемое значение в комментарий. В книге «Programming Ruby» рассматривается xmp
, а также библиотека rtags
(которая генерирует файл TAGS для редакторов emacs или vi). У
irb
есть еще одна приятная особенность, о которой стоит знать. Понятно, что irb
умеет анализировать написанный на Ruby код, но лексический анализатор несложно использовать и в других приложениях. Вот простой пример программы, которая открывает саму себя и анализирует собственный код, выводя отсортированный список всех идентификаторов и констант:
require 'irb/ruby-lex'
file = File.new(__FILE__)
parse = RubyLex.new # (file)
parse.set_input(file)
idents = []
loop do
token = parse.token
break if token.nil?
if token.is_a? RubyToken::TkIDENTIFIER or
token.is_a? RubyToken::TkCONSTANT
idents << token.name
end
end
p idents.uniq.sort
# Выводится:
# ["File", "RubyLex", "RubyToken", "TkCONSTANT", "TkIDENTIFIER", "file",
# "idents", "loop", "name", "new", "p", "parse", "require", "set_input",
# "sort", "token", "uniq"]
Насколько мне известно, этот механизм не документирован на английском языке. Но если вам необходим лексический анализатор Ruby, то можете изучить исходный текст и адаптировать его под свои нужды.
Поделиться с друзьями: