self % 100 != 0) || self % 400 == 0 end def year days = 0 current_year = Time.now.year self.times do |n| days += (current_year + n + 1).leap_year? ? 366 : 365 end return 3600 * 24 * days end alias years year end
end end module ClassMethods def new(*args) @instance = super(*args) unless @instance return @instance end end module InstanceMethods def singleton?; true end end end
100 end def do_somethind # Проверка наличия блока yield 100 if block_given? end do_something { |n| n.to_s(2) } #=> "1100100" do_something do |n| n ** 2 end #=> 10000
GIL). • Сложность разработки многопоточных приложений. • Относительно низкая производительность. • Нет проверки типов аргументов методов и возвращаемого значение. • Динамичностью и метапрограмированием можно отстрелить сразу обе ноги.
Twitter, LivingSocial, Basecamp, Groupon, ...) • В основном для web • И еще в отличных инструментах для разработчиков и не только (Vagrant, Chef, Metasploit, Capistrano, ...)
class ArticlesController < ApplicationController # http://localhost:3000/articles def index @articles = Article.order('published_at DESC') .includes(:author) end # http://localhost:3000/articles/:id def show @article = Article.find(params[:id]) @comments = @article.comments end end
не то, как реализована функциональность. • Проектирование в момент написания спецификаций. • Спецификации служат документацией по коду проекта. • Тестирование предоставляет максимум информации о “красных” тестах.
context 'when amount = 0' do let :args do {amount: 0, percent: 22, period: 10} end it ‘returns 0’ do expect(described_class.calc(args)).to be_zero end end #... #... end
на переключение. • Заказчик видит в списке задач только ценные тикеты. • Технический долг постепенно минимизируется. • Никаких “Потом” • Никаких авралов* *почти правда
код. • Быстрые тесты - хорошие тесты. • Mocking для внешних сервисов. • Mocking / Stubbing хороши, но в меру. • Важно не количество спеков / тестов, а покрытие.