My guiding light is Kent Beck's rules of Simple Design (източник):
- The code must first be correct (as defined by tests);
- then it should be a clear statement of the design (what J.B.Rainsberger calls "no bad names");
- then it should contain no duplication (of text, of ideas, or of responsibility);
- and finally it must be the smallest code that meets all of the above.
It's time to stop refactoring when the code makes a reasonable stab at meeting those goals, and when any further changes would add no further benefit.
Досега говорихме за:
String
)
Fixnum
) и с плаваща запетая (Float
)
TrueClass
, FalseClass
NilClass
Bignum
(core)
BigDecimal
(stdlib)
Rational
Complex
Rational
Rational(a, b)
или с литерален синтаксис (само в 2.1): 0.1r
И такъв вграден тип има, Complex
(документация):
Complex(1) # (1+0i)
Complex(2, 3) # (2+3i)
Complex('0.3-0.5i') # (0.3-0.5i)
Complex('2/3+3/4i') # ((2/3)+(3/4)*i)
3.to_c # (3+0i)
0.3.to_c # (0.3+0i)
'0.3-0.5i'.to_c # (0.3-0.5i)
'2/3+3/4i'.to_c # ((2/3)+(3/4)*i)
'1@2'.to_c # (-0.4161468365471424+0.9092974268256817i)
Колко от вас са запознати със следните неща:
map
и filter
Минимално необходимо знание за всеки програмист. Поставете си го за цел.
Един обект се обръща до низ с #to_s
. Има и друг вариант, #inspect
,
който го обръща до текстов низ, изглеждащ като ruby код. Целта е инспектиране.
puts(something)
извежда something.to_s
p(something)
извежда something.inspect
#
е коментар
#puts
, Array#inject
"The answer: #{40 + 2}"
C#
Array
. Разбира се, има литерален синтаксис
[1, 2, 3, 4]
[18, :female, 'Burgas']
numbers = [:zero, :one, :two]
numbers[1] # :one
numbers[10] # nil
numbers[-1] # :two
numbers[5] = :five
numbers[5] # :five
numbers # [:zero, :one, :two, nil, nil, :five]
Array#fetch
хвърля грешка или връща друга стойност, при индексиране извън обема на масива:
numbers = [:zero, :one, :two]
numbers.fetch(1) # :one
numbers.fetch(10) # error: IndexError
numbers.fetch(10) { |n| puts "#{n} isn't in array" } # вместо IndexError, се изпълнява кодът между { }
numbers.fetch(10, :dunno) # :dunno
numbers[10] or :dunno # като предното, ама не точно
Ползва се по-рядко, отколкото си мислите.
numbers = [3, 1, 2, 4]
numbers.length # 4
numbers.size # 4
numbers.sort # [1, 2, 3, 4]
numbers.reverse # [4, 2, 1, 3]
numbers[1..2] # [1, 2]
sort
и reverse
връщат нов масив, без да променят numbers
.
#include?
ви казва дали масив съдържа даден елемент.
prime_digits = [2, 3, 5, 7]
prime_digits.include? 2 # true
prime_digits.include? 4 # false
Внимание: линейно търсене. Подходящо за малки списъци.
[:a, :b, :c] + [:d, :e] # [:a, :b, :c, :d, :e]
[:a, :b, :c, :b, :a] - [:b, :c, :d] # [:a, :a]
[:a, :b, :c] & [:b, :c, :d] # [:b, :c]
[:a, :b, :c] | [:b, :c, :d] # [:a, :b, :c, :d]
&
и |
конкатенират списъците и премахват повторенията.
В Ruby има множества, които са по-удачни в повечето случаи.
numbers = [1, 2, 3]
numbers << 4
p numbers # [1, 2, 3, 4]
numbers.insert 0, :zero
p numbers # [:zero, 1, 2, 3, 4]
result = numbers.delete_at(0)
p result # :zero
p numbers # [1, 2, 3, 4]
stack = [1, 2, 3]
stack.push 4
p stack # [1, 2, 3, 4]
top = stack.pop
p stack # [1, 2, 3]
p top # 4
#shift
и #unshift
са аналогични, но работят с началото на масива.
[1, 2, 3].join("-") # "1-2-3"
[1, 2, 3].permutation # сещате се какво връща
[1, 2].product([3, 4]) # [[1, 3], [1, 4], [2, 3], [2, 4]]
[[1, 2], [3, 4]].transpose # [[1, 3], [2, 4]]
[1, 2, 3, 4].shuffle # разбърква масива произволно
Има редица такива методи, които може да намерите в Ruby Doc.
Може да оставите запетая след последния елемент на масива. Така редовете се разместват по-лесно. Важи и за хешове.
songs = [
'My Favorite Things',
'Alabama',
'A Love Supreme',
]
Има специален синтаксис за масив от думи.
%w(chunky bacon) == ['chunky', 'bacon']
%w[a b c] == ['a', 'b', 'c']
%w{cool stuff} == ['cool', 'stuff']
%w<coffee tea water> == ['coffee', 'tea', 'water']
%w|foo bar| == ['foo', 'bar']
Може да използвате различни видове символи, които да ограждат думите от масива:
! @ # $ * - _
Този списък от символи е непълен.
slice
(документация)
[]
е всъщност метод на Array
, който е синоним на slice
[]=
от своя страна позволява и да променяте въпросните отрязъци от масиваnumbers = [1, 2, 3, 4, 5, 6]
numbers[0..2] # [1, 2, 3]
numbers[-3..-1] # [4, 5, 6]
numbers[1, 1] # [2]
numbers[0..2] = [:wat]
numbers # [:wat, 4, 5, 6]
Итерира се с #each
, както всичко останало в Ruby:
primes = [2, 3, 5, 7, 11]
primes.each { |n| puts n }
primes.each do |n|
puts n
end
for
#each
do
/end
се ползва, когато блокът е няколко редаHash
, но има и литерален синтаксис – {}
{1 => :one, 2 => :two}
numbers = {:one => :eins, :two => :zwei}
numbers[:one] # :eins
numbers[:three] # nil
numbers[:three] = :drei
numbers[:three] # :drei
numbers.fetch(:four, :keine_ahnung) # :keine_ahnung
numbers.fetch(:four) # error: KeyError
numbers = {:one => :eins, :two => :zwei}
numbers.keys # [:one, :two]
numbers.values # [:eins, :zwei]
numbers.each { |pair| puts pair }
numbers.each { |key, value| puts key, value }
numbers = {1 => 2, 3 => 4}
numbers.has_key?(:three) # false
numbers.size # 2
numbers.invert # {2=>1, 4=>3}
numbers.merge({5 => 6}) # {1=>2, 3=>4, 5=>6}
numbers.to_a # [[1, 2], [3, 4]]
Hash[1, 2, 3, 4] # {1=>2, 3=>4}
Долните два реда произвеждат еднакви хешове. Второто е 1.9+ синтаксис и ще предпочитаме него по конвенция (когато може):
{:one => 1, :two => 2}
{one: 1, two: 2}
Има интересна врътка при извикването на методи, за която ще споменем малко по-натам.
Enumerable
)