->_{_%_}["->_{_%%_}[%r]"]
v=0000;eval$s=%q~d=%!^Lcf<LK8, _@7gj*LJ=c5nM)Tp1g0%Xv.,S[<>YoP
4ZojjV)O>qIH1/n[|2yE[>:ieC "%.#% :::##" 97N-A&Kj_K_><wS5rtWk@*a+Y5
yH?b[F^e7C/56j|pmRe+:)B "##% ::##########" O98(Zh)'Iof*nm.,$C5Nyt=
PPu01Avw^<IiQ=5$'D-y? "##: ###############" g6`YT+qLw9k^ch|K'),tc
6ygIL8xI#LNz3v}T=4W "# #. .####:#######" lL27FZ0ij)7TQCI)P7u
}RT5-iJbbG5P-DHB<. " ##### # :############" R,YvZ_rnv6ky-G+4U'
$*are@b4U351Q-ug5 " #######################" 00x8RR%`Om7VDp4M5
PFixrPvl&<p[]1IJ " ############:#### %#####" EGgDt8Lm#;bc4zS^
y]0`_PstfUxOC(q " .#############:##% .## ." /,}.YOIFj(k&q_V
zcaAi?]^lCVYp!; " %% .################. #. " ;s="v=%04o;ev"%
(;v=(v-($*+[45, ":####: :##############% : " ])[n=0].to_i;)%
360)+"al$s=%q#{ "%######. ######### " ;;"%c"%126+$s<<
126}";d.gsub!(/ "##########. #######% " |\s|".*"/,"");;
require"zlib"|| "########### :######. " ;d=d.unpack"C*"
d.map{|c|n=(n|| ":#########: .######: . " )*90+(c-2)%91};
e=["%x"%n].pack " :#######% :###### #: " &&"H*";e=Zlib::
Inflate.inflate( " ######% .####% :: " &&e).unpack("b*"
)[0];22.times{|y| " ####% %### " ;w=(Math.sqrt(1-(
(y*2.0-21)/22)**(; " .###: .#% " ;2))*23).floor;(w*
2-1).times{|x|u=(e+ " %## " )[y*z=360,z]*2;u=u[
90*x/w+v+90,90/w];s[( " #. " ;y*80)+120-w+x]=(""<<
32<<".:%#")[4*u.count(( " . " ;"0"))/u.size]}};;puts\
s+";_ The Qlobe#{" "*18+ ( "# :#######" ;"Copyright(C).Yusuke End\
oh, 2010")}";exit~;_ The Qlobe Copyright(C).Yusuke Endoh, 2010
Exception
и StandardError
.
StandardError < Exception
.Object +-- Exception +-- NoMemoryError +-- ScriptError | +-- SyntaxError | +-- LoadError +-- SecurityError +-- StandardError +-- ArgumentError +-- IndexError | +-- KeyError | +-- StopIteration +-- NameError | +-- NoMethorError +-- RuntimeError +-- TypeError
После ще видим пълната.
# Предизвиква RuntimeError
raise "'Prophet!' said I, 'Thing of evil!" # error: RuntimeError
# Като горното, но с различен текст
raise RuntimeError, 'prophet still, if bird or devil!' # error: RuntimeError
# Друг начин да предизвикаме RuntimeError
raise RuntimeError.new('Whether tempter sent, or whether...') # error: RuntimeError
begin
puts '...tempest tossed thee here ashore'
raise NameError, 'Desolate yet all undaunted'
rescue => ex
ex.message # "Desolate yet all undaunted"
ex.class # NameError
end
begin
raise KeyError, 'on this desert land enchanted'
rescue ArgumentError => ex
puts 'on this home by horror haunted'
rescue KeyError, TypeError => ex
ex.message # "on this desert land enchanted"
ex.class # KeyError
end
rescue
хваща "само" наследници на StandardError
, ако не сме указали друго:
Object +-- Exception +-- NoMemoryError +-- ScriptError +-- StandardError +-- ArgumentError +-- NameError | +-- NoMethorError +-- RuntimeError
begin
raise KeyError, 'tell me truly, I implore'
rescue IndexError => ex
puts 'IndexError'
rescue KeyError => ex
puts 'KeyError'
end
Припомняне KeyError < IndexError
$eh = 'foo'
begin
raise KeyError, 'Is there - is there balm in Gilead?'
rescue IndexError => ex
$eh = 'index'
rescue KeyError => ex
$eh = 'key'
end
$eh # "index"
Изпълнява се първия rescue
, за който изключението е kind_of?
типа.
Динамичните езици обикновено ползват прости правила
Кодът в ensure
клаузата се изпълнява винаги.
begin
raise 'tell me - tell me, I implore!' if rand(2).zero?
ensure
puts '????? ??? ?????, "?????????"'
end
rand(2).zero?
връща true
или false
, 50 на 50.else
клаузата се изпълнява когато няма възникнало изключение.
begin
launch_nukes
rescue
puts 'Uh-oh! Something went wrong :('
else
puts 'War... War never changes'
end
launch_nukes
няма удивителна.
begin
get_a_life
rescue NoFriendsError => ex
puts 'Goodbye cruel world'
rescue InsufficientVespeneGasError, NotEnoughMineralsError => ex
puts 'I think I play too much StarCraft'
rescue
puts ';('
else
puts 'Woohoo!'
ensure
puts 'rm -rf ~/.history'
end
В случай, че ползвате rescue
в метод така:
def execute
begin
potentially_dangerous
rescue SomeException => e
# Handle the error
ensure
# Ensure something always happens
end
end
По-добре е да го запишете без begin
/end
, което е еквивалентно на предното:
def execute
potentially_dangerous
rescue SomeException => e
# Handle the error
ensure
# Ensure something always happens
end
Ако възникне изключение при обработка друго, старото се игнорира и се "вдига" новото.
begin
raise KeyError
rescue
raise TypeError
puts "I'm a line of code, that's never executed ;("
end
raise
в rescue
клауза "вдига" същото
изключение, което се обработва.
begin
raise KeyError, 'But high she shoots through air and light'
rescue
puts 'Whoops'
raise
end
result = begin
raise KeyError if rand(3).zero?
raise NameError if rand(3).zero?
rescue KeyError
'nyckel'
rescue NameError
'namn'
else
'ingenting'
end
result # "nyckel"
rescue
може да се ползва като модификатор.StandardError
.[].fetch(1) rescue 'baba' # "baba"
raise type, message
всъщност извиква type.exception(message)
за да конструира изключение.
class Thing
def exception(message)
NameError.new(message)
end
end
thing = Thing.new
raise thing, 'whoops' # error: NameError
Може да разделим изключенията на два вида.
rescue
.За първите обикновено създаваме клас. За вторите обикновено ползваме raise
.
KeyError
или IndexError
. Защо?
raise
и rescue
.def iterate_pairs(hash)
hash.values.each { |array| iterate_values array }
end
def iterate_values(array)
array.each do |item|
if item == 'Nemo'
puts 'Found Nemo!'
throw :done
end
end
end
animals = {cats: %w[Simba], fish: %w[Crispy Nemo], boars: %w[Pumba]}
catch(:done) { iterate_pairs(animals) }
Този пример е доста синтетичен.
catch
приема символ и блок.
throw
със същия символ.
catch
.
catch
-а.
throw
взема допълнителен аргумент, който е върнатата стойност на catch
.
throw
, стойността на catch
е последния оценен израз.Някои методи на Enumerable
могат да не вземат блок.
numbers = []
1.upto(5) { |x| numbers << x }
numbers # [1, 2, 3, 4, 5]
other = 1.upto(5)
other # #<Enumerator: 1:upto(5)>
other.to_a # [1, 2, 3, 4, 5]
1.upto(5).map(&:succ) # [2, 3, 4, 5, 6]
Енумераторите могат да се държат като итератори.
numbers = 1.upto(3)
numbers.next # 1
numbers.next # 2
numbers.next # 3
numbers.next # error: StopIteration
loop
прави безкраен цикъл. Спира на StopIteration
.
numbers = 1.upto(3)
loop do
puts numbers.next
end
Енумераторите имат някои интересни методи.
numbers = 1.upto(3)
numbers.with_index.to_a # [[1, 0], [2, 1], [3, 2]]
numbers.with_object(:x).to_a # [[1, :x], [2, :x], [3, :x]]
Може да извадите енумератор от произволен метод с enum_for
.
class Numbers
def primes
yield 2
yield 3
yield 5
yield 7
end
end
first_four_primes = Numbers.new.enum_for(:primes)
first_four_primes.to_a # [2, 3, 5, 7]
Ако ви се е случвало да ви трябва индекс в map
:
words = %w( foo bar baz ).map.with_index do |word, index|
"#{index}: #{word.upcase}"
end
words # ["0: FOO", "1: BAR", "2: BAZ"]