Ruby/Идеология: различия между версиями

Содержимое удалено Содержимое добавлено
стилевые правки
Строка 62:
 
В большинстве случаев, можно обойтись без циклов. Было бы желание. Для примера перепишем одну из программ, представленных на вышеописанном сайте.
<codesource lang=ruby>m, n = 2, 2
while m <= 5
m, n = m + 2, n + m
end
puts "m=#{m}"
puts "n=#{n}"</codesource>
Ее можно переписать в виде:
<codesource lang=ruby>n = 2
2.step(5,2){ |m| n += m }
puts "n=#{n}" # m - локальная переменная внутри блока, вне блока ее не существует</codesource>
Стоит заметить, что во втором фрагменте мы избавились от ненужной глобальной переменной, которую превратили в локальный счетчик итератора. При этом была использована информация о конечном значении счетчика. Стоит ли использовать циклы, если они порождают массу проблем? А именно:
* Ухудшение читабельности кода.
Строка 228:
Теперь надо как-то назвать эту структуру. После недолгих раздумий, было решено именовать ее Contract и построить ее на базе класса Hash, добавив к нему всего два метода: <code>.add_contract</code> и <code>.find_contracts</code>. Вот их реализация и коротенький пример:
 
<codesource lang=ruby>class Hash
def add_contract(key, &block)
self[ key ] = block
Строка 244:
hash = {}
hash.add_contract( 5 ){ |i| puts i }
p hash.find_contracts{ |i| i == 5 } #-> [#<Proc:0x02777bf8@test019.rbw:40>]</codesource>
 
Как видно, результатом является массив "проков", где для обработки каждого "прока" надо вызвать метод <code>.call</code>. [[Участник:Rubynovich|Rubynovich]] 19:07, 9 июня 2006 (UTC)
Строка 263:
Контролировать тип входных данных, которые передаются в метод, можно по-разному. Например, вызывая метод <code>.class</code>, который возвращает класс, к которому принадлежит передаваемый объект.
 
<codesource lang=ruby>def meTog( napameTp_1 )
raise "Не тот тип входных данных!" if [<u>String</u>, <u>Array</u>].include?( napameTp_1<u>.class</u> )
case napameTp_1.class
Строка 271:
napameTp
end.map{ |s| s.to_i }
end</codesource>
 
{{info|Метод <code>.class</code> возвращает объект класса <code>Class</code>, то есть код <code><nowiki>o6bekT.class.class == Class</nowiki></code> будет всегда возвращать <code>true</code>}}
Строка 283:
Давайте реализуем предыдущий код, но с использованием расширения класса.
 
<codesource lang=ruby>class String
def meTog
split('')<u>.meTog</u>
Строка 295:
end
napameTp_1.meTog</codesource>
 
В зависимости от класса, будет вызван либо один <code>meTog</code>, либо другой. При этом, <code>meTog</code> в классе <code>String</code> используется как адаптер для <code>meTog</code>'а класса <code>Array</code>. Единственный недостаток такого подхода — случайное переопределение базовых методов. Но эта случайность быстро отлавливается. [[Участник:Rubynovich|Rubynovich]] 17:40, 5 ноября 2006 (UTC)