require
Какво прави alias
?
class Something
def name() 'baba' end
alias relative name
def name() 'dyado' end
end
p Something.new.relative
Прави копие на метода
Каква е разликата между alias
и alias_method
?
alias_method
е метод, докато alias
е синтаксис
class Something
1.upto(5).each do |index|
alias_method "to_s_#{index}", :to_s
end
end
Какво ще се случи след изпълнение на примерния код по-долу – грешка, или конкретна оценка? Каква?
module Outer
class String
def the_answer() '42' end
end
module Inner
String.new.the_answer
end
end
Кодът по-горе се оценява на низа '42'
. Причината е, че "вътрешната" константа String
"засенчва" глобалната такава. Допълнително, оценката на кода е последно изпълненият ред, който е String.new.the_answer
.
В следния примерен код, по какви начини бихме могли да достъпим константата TREASURE
от мястото, отбелязано с коментар?
module Deep
module Down
module Below
TREASURE = 'Ya fools.'
end
end
# =>
end
Поне по следните начини:
Down::Below::TREASURE
Deep::Down::Below::TREASURE
Object::Deep::Down::Below::TREASURE
::Deep::Down::Below::TREASURE
::Object::Deep::Down::Below::TREASURE
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:0x424a7684>:0x424a7648>
Class.new.new # #<#<Class:0x424a73f0>:0x424a73c8>
Module.new # #<Module:0x424a7224>
Можем да подадем блок на 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:0x42702a8c>
Person = Class.new # Person
Module.new # #<Module:0x42702690>
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
->_{_%_}["->_{_%%_}[%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
Да кажем, че имаме следния код:
CURRENCY_NAMES = {
BGN: 'Bulgarian lev',
EUR: 'Euro',
USD: 'United States dollar',
CHF: 'Swiss frank',
}.freeze
[:BGN, :CHF, :EUR].map { |currency_code| CURRENCY_NAMES[currency_code] }
# => ["Bulgarian lev", "Swiss frank", "Euro"]
Нека предположим, че имаме следната имплементация на Hash#to_proc
:
class Hash
def to_proc
proc { |key| self[key] }
end
end
Тогава можем да направим следното:
CURRENCY_NAMES = {
BGN: 'Bulgarian lev',
EUR: 'Euro',
USD: 'United States dollar',
CHF: 'Swiss frank',
}.freeze
[:BGN, :CHF, :EUR].map &CURRENCY_NAMES
# => ["Bulgarian lev", "Swiss frank", "Euro"]
Удобни изглеждат и следните хипотетични употреби:
VALID_CURRENCIES = {
BGN: true,
EUR: true,
USD: true,
CHF: true,
}.freeze
valid_currencies = [:BGN, :CHF, :EUR].select(&VALID_CURRENCIES)
# Or:
if currencies.any? &VALID_CURRENCIES
end
# Or:
words.reject(&FORBIDDEN_WORDS)
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
Ruby позволява да обедините проверката за няколко възможни стойности в един when
, дори да не са от един и същи тип.
case number
when (42+0i) then 'This is too complex for me!'
when 42, 42.0 then 'This is more like it!'
end
when
case
, например:thing = 42
case
when thing == 1 then 1
else 'no_idea'
end
if
-овеСега е моментът.
В 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
Следващия път ще продължим с разглеждане структурата на един gem и ще пробваме да се спуснем в пещерата на skeptic. Ще демонстрираме основни пещернячески умения.