case
в Ruby
require
String.methods
)
String.class
) и той е Class
Долното работи:
a_hash_class = Hash
a_hash_class.new # {}
Class.new
Module.new
ще създаде инстанция на анонимен модулanonymous_class = Class.new
anonymous_class.new # #<#<Class:0x41089738>:0x41089710>
Class.new.new # #<#<Class:0x410894f4>:0x410894cc>
Module.new # #<Module:0x41089300>
Можем да подадем блок на Class.new
:
duck = Class.new do
def quack_to(creature_name)
"Quack, #{creature_name}, quack!"
end
end
duck.new.quack_to("swan") # "Quack, swan, quack!"
class Person
end
class
е просто синтаксис, който прави обект от тип "клас"
class
е scope gate, докато блоковете не са
class
го присвоява и на константа
Когато присвоим анонимен клас на константа, попадаме в специален случай:
Person = Class.new
Class.new # #<Class:0x421bcb7c>
Person = Class.new # Person
Module.new # #<Module:0x421bc71c>
Larodi = Module.new # Larodi
::
Object
Object::FOO
и ::FOO
в (почти) всички случаи са едно и също
::Object::FOO
и ::FOO
са едно и също винагиObject
Можете да видите тази "таблица" през constants
:
module MyLibrary
class Object
end
end
MyLibrary.constants # [:Object]
MyLibrary::Object == Object # false
class Foo::Bar
# In the Bar scope, but not in the Foo scope
end
class
и module
В този пример:
class Foo::Bar
Larodi
end
Bar
и я записваме в таблицата с константи на Foo
Foo
трябва да съществува предварително; може да бъде или модул, или клас
Larodi
ще се търси в таблицата на Bar
и след това в root scope-а
Foo
module A::B
module C::D
Foo # Where does Ruby look for Foo?
end
end
D
B
Object
)Имате ли въпроси?
В Ruby има "switch". Казва се case
.
def quote(name)
case name
when 'Yoda'
puts 'Do or do not. There is no try.'
when 'Darth Vader'
puts 'The Force is strong with this one.'
when 'R2-D2'
puts 'Beep. Beep. Beep.'
else
puts 'Dunno what to say'
end
end
break
when
не мине, изпълнява се else
when
не мине, и няма else
, не става нищо
case
е израз, което значи, че връща стойностcase operation
when :& then puts 'And?'
when :| then puts 'Or...'
when :! then puts 'Not!'
else puts 'WAT?'
end
На какво ще се оцени следният код?
case 'Wat?'
when 'watnot' then puts "I'm on a horse."
end
Ако няма else
и никой when
не match-не, се връща nil
.
case
не сравнява с ==
. Може да напишете следното:
def qualify(age)
case age
when 0..12
'still very young'
when 13..19
'a teenager! oh no!'
when 33
'the age of jesus'
when 90..200
'wow. that is old!'
else
'not very interesting'
end
end
case
сравнява с ===
. Няколко класа го имплементират:
Range
Regexp
Class
==
def qualify(thing)
case thing
when Integer then 'this is a number'
when String then 'it is a string'
when Array then thing.map { |item| qualify item }
else 'huh?'
end
end
case hours_of_sleep
when 8..10 then 'I feel fine.'
when 6...8 then 'I am a little sleepy.'
when 0..3 then 'OUT OF MY WAY! I HAVE PLACES TO BE AND PEOPLE TO SEE!'
end
def parse_date(date_string)
case date_string
when /(\d{4})-(\d\d)-(\d\d)/
Date.new $1.to_i, $2.to_i, $3.to_i
when /(\d\d)\/(\d\d)/(\d{4})/
Date.new $3.to_i, $1.to_i, $2.to_i
end
end
when
case
, например:thing = 42
case
when thing == 1 then 1
else 'no_idea'
end
if
-овеСега е моментът.
->_{_%_}["->_{_%%_}[%p]"]
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
Може да пуснете quine-а от предния слайд като го запазите във файл quine.rb
и ползвате това скриптче:
#!/bin/sh
while true
do
ruby quine.rb | tee quine_result
mv quine_result quine.rb
sleep 0.2
done
В Ruby, код от други файлове се импортира с require
.
Например:
require 'bigdecimal'
require 'bigdecimal/util'
require 'foo'
търси файл foo.rb
в "пътя за зареждане"
require 'foo/bar'
търси директория foo
с файл bar.rb
.rb
отзад не е задължително да присъства
require './foo'
търси foo.rb
в текущата директория
require '/home/skanev/foo.rb'
require './foo'
require_relative
require_relative 'foo'
зарежда 'foo' спрямо директорията на изпълняващия се файл
require './foo'
зарежда спрямо текущата директория на изпълняващия процес$LOAD_PATH
$:
$:.unshift(path)
require
-а. Почти
main
обекта е същия
require
-и не правят нищо
require
може да зарежда .so
и .dll
файлове$LOAD_PATH
. ├── README.rdoc ├── Rakefile ├── bin │ └── skeptic ├── features ├── lib │ ├── skeptic │ │ ├── rules.rb │ │ └── scope.rb │ └── skeptic.rb ├── skeptic.gemspec └── spec
lib/
обикновено съдържа foo.rb
и lib/foo/
foo.rb
обикновено е единственото нещо в lib/
lib/foo
lib/
се добавя в load path
require 'foo'
или require 'foo/something'
require
областта
require
и $LOAD_PATH
и вижте какво се случва
load
е много сходен с require
, но има няколко разлики
load 'foo.rb'
load
-ове изпълняват файла
load
не може да зарежда .so
/.dll
библиотеки
load
има опционален параметър, с който може да обвие файла в анонимен модул
Имате ли въпроси по require
, load
, gem-ове в Ruby?
Някои методи на 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"]