SlideShare a Scribd company logo
Ruby: Beauty and the Beast Александр Дымо IT-клуб Николаева www.acunote.com
О чем речь? Опыт разработки на Ruby (+Rails) веб-приложения Acunote  www.acunote.com ,[object Object]
29 000 строк кода
45 500 строк тестов
~12000 зарегистрированных организаций
О чем речь? ,[object Object],[object Object]
Что не понравилось
Интересные особенности ,[object Object],[object Object]
Garbage Collection ,[object Object],[object Object]
Тестирование
Профилировка и производительность
Деплоймент ,[object Object]
Язык Ruby: Что понравилось Меньше кода – больше кислорода! ~3-4 разработчика * ~5 лет = 29k строк???
Язык Ruby: Что понравилось Меньше кода – больше кислорода! 400 строк на Ruby == 6000 на C++
Язык Ruby: Что понравилось Уж больно хорошо все выглядит! module  SearchLanguage class  Parser class  ParseError < StandardError;  end def  self. parse (text) parser = Parser. new parser. parse (text) end private : def  parse_search_query parse_and_expression end def  parse_and_expression match_spaces node = ExpressionNode. new (:and) return  node  if  empty_buffer? node. expressions  << parse_or_expression while  match_AND  and  !empty_buffer?  and  !end_of_subexpression? node. expressions  << parse_or_expression end node end end end
Язык Ruby: Что понравилось Методы с ! и ? [1,2,3] . include?   2 &quot;foo bar&quot; . gsub ( &quot;o&quot; ,  &quot;a&quot; ) &quot;foo bar&quot; . gsub! ( &quot;o&quot; ,  &quot;a&quot; )
Язык Ruby: Что понравилось Методы с ! и ? class  Foo def  transform! #... end def  transformed? #... end end
Язык Ruby: Что понравилось Элегантный подход к getters/setters class  Foo attr_accessor :foo end class  Foo def  foo @foo end def  foo=(value) @foo = value end end f = Foo.new f.foo = 2 # f.foo=(2) puts f.foo
Язык Ruby: Что понравилось Блоки def  do_smth(&block) puts yield(10) puts yield(20) end do_smth { |value| value + 5 } >  15 >  25
Язык Ruby: Что понравилось Возможность встроиться куда угодно class  Time def  humanize strftime(&quot;%a %b %d, %Y %H:%M&quot;) end end puts  Time.now.humanize > Thu Apr 21, 2011 13:37 ...мы дополнили 28 различных классов
Язык Ruby: Что понравилось Возможность встроиться куда угодно class  BigDecimal alias_method  :eq_without_boolean_comparison, :== def  eq_with_boolean_comparison(other) if  [FalseClass, TrueClass].include? other.class return  false end eq_without_boolean_comparison(other) end alias_method  :==, :eq_with_boolean_comparison end
Язык Ruby: Что понравилось Правильный способ встраивания/расширения class  Foo def  do_smth puts  &quot;Hello World&quot; end end class  Foo def  do_smth_with_decoration puts  &quot;--------------&quot; do_smth_without_decoration puts  &quot;--------------&quot; end end f = Foo.new f.do_smth >  -------------- >  Hello World >  --------------
Язык Ruby: Что понравилось Возможность переписать все что угодно class  Foo { private: void  doSmth() { std::cout  <<  &quot;Hello World&quot; } }; ... class  Foo def  doSmth puts  &quot;Hi&quot; end end f = Foo.new f.doSmth >  Hi
О чем речь? ,[object Object],[object Object]
Что не понравилось
Интересные особенности ,[object Object],[object Object]
Garbage Collection  ,[object Object],[object Object]
Тестирование
Профилировка и производительность
Деплоймент ,[object Object]
Язык Ruby: Что не понравилось Perl'измы в синтаксисе x = false or true puts x  #???
Язык Ruby: Что не понравилось Perl'измы в синтаксисе x = false or true (x = false) or true puts x >  false
Язык Ruby: Что не понравилось Perl'измы в синтаксисе x = false || true x = (false || true) puts x >  true
Язык Ruby: Что не понравилось Perl'измы в синтаксисе x = 2  if  false or true puts x > ?
Язык Ruby: Что не понравилось Perl'измы в синтаксисе x = 2  if  false or true x = 2  if  (false or true) puts x > 2
Язык Ruby: Что не понравилось Python'измы в синтаксисе class  Foo attr_accessor  :x def  do_smth x = 10 end end f = Foo.new f.x >  nil #WTF?
Язык Ruby: Что не понравилось Python'измы в синтаксисе class  Foo attr_accessor  :x def  do_smth self. x = 10 end end f = Foo.new f.x >  10
Язык Ruby: Что не понравилось Переменные экземпляров классов class  Foo attr_accessor  :x def  initialize @x  = 10 #или self.x  = 10 y =  @x #или y = x end end
О чем речь? ,[object Object],[object Object]
Что не понравилось
Интересные особенности ,[object Object],[object Object]
Garbage Collection ,[object Object],[object Object]
Тестирование
Профилировка и производительность
Деплоймент ,[object Object]
Язык Ruby: Интересные особенности Модули: пространства имен  или решение проблемы множественного наследования module  ActiveRecord module  ConnectionAdapters class  MysqlAdapter def  execute #... end end end end module  ActiveRecord module  Validations def  valid? errors.empty? end end class  Base include  Validations end end
Язык Ruby: Интересные особенности Блоки: передача функций в другие функции  или предусловия/постусловия def  calculate(&algorithm) yield (2, 2) end result = calculate  do  |x,y| x + y end def  calculate(&expression) return  unless can_calculate? result =  yield result.good?  ?  result  :  nil end result = calculate  do 2+2 end
Язык Ruby: Интересные особенности method_missing class  GoldenFish def  method_missing(name, *args, &block) if  name == :make_me_rich puts &quot;here you go: $1 000 000&quot; else puts &quot;you want too much!&quot; end end end fish = GoldenFish.new fish.make_me_rich >  here you go: $1 000 000 fish.make_my_old_wife_a_supermodel > you want too much!
Язык Ruby: Интересные особенности Ассоциации в Rails: реализация с method_missing class  User has_many :roles end user = User.find(:first) #метод ассоциации user.roles.find(:all, :conditions => &quot;name = 'Admin'&quot;) #метод массива user.roles.map { |role| role.name }
Язык Ruby: Интересные особенности Ассоциации в Rails: реализация с method_missing class  AssociationProxy def  reload @target = [1,2,3]  #just for an example end def  method_missing(method, *args, &block) if  @target.respond_to? method @target.send(method, *args, &block) else raise  NoMethodError end end end end p = AssociationProxy.new p.reload #вызываем свой метод p << 3 #вызываем метод класса Array (у @target)
О чем речь? ,[object Object],[object Object]
Что не понравилось
Интересные особенности ,[object Object],[object Object]
Garbage Collection ,[object Object],[object Object]
Тестирование
Профилировка и производительность
Деплоймент ,[object Object]
Ruby Runtime: Что с ним так и не так
Ruby Runtime: Что с ним так и не так Ruby – это красиво, удобно, мощно... но где же подвох?
Ruby Runtime: Что с ним так и не так Ruby – это   медленно !
Ruby Runtime: Что с ним так и не так Ruby – это   очень  медленно !
Ruby Runtime: Что с ним так и не так Апрель 2008 Май 2008 Июнь 2008 Июль 2008 Время обслуживания запроса, % Худший случай: O(n a ) В среднем: O(log n)
О чем речь? ,[object Object],[object Object]
Что не понравилось
Интересные особенности ,[object Object],[object Object]
Garbage Collection ,[object Object],[object Object]
Тестирование
Профилировка и производительность
Деплоймент ,[object Object]
Ruby Runtime: Garbage Collection Сборка мусора – самое плохое  что может произойти с вашим Ruby кодом!

More Related Content

What's hot

Rubinius: Ruby написанный на Ruby
Rubinius: Ruby написанный на RubyRubinius: Ruby написанный на Ruby
Rubinius: Ruby написанный на Ruby
Ivan Samsonov
 
Павел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладкаПавел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладка
Sergey Platonov
 
Scala: что, как и зачем?
Scala: что, как и зачем?Scala: что, как и зачем?
Scala: что, как и зачем?Roman Timushev
 
Scala для всех (РИФ 2015)
Scala для всех (РИФ 2015)Scala для всех (РИФ 2015)
Scala для всех (РИФ 2015)
Арсений Жижелев
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Platonov Sergey
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Platonov Sergey
 
JPHP - О проекте на простом языке
JPHP - О проекте на простом языкеJPHP - О проекте на простом языке
JPHP - О проекте на простом языке
Dmitry Zaytsev
 
DLR Hosting
DLR HostingDLR Hosting
DLR Hosting
Vitaly Baum
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Yauheni Akhotnikau
 
Эффективный C++
Эффективный C++Эффективный C++
Эффективный C++
Andrey Karpov
 
Михаил Давыдов: JavaScript. Базовые знания
Михаил Давыдов: JavaScript. Базовые знанияМихаил Давыдов: JavaScript. Базовые знания
Михаил Давыдов: JavaScript. Базовые знанияYandex
 
Иван Стеценко: ЯП Zephir. Панацея или лечение?
Иван Стеценко: ЯП Zephir. Панацея или лечение?Иван Стеценко: ЯП Zephir. Панацея или лечение?
Иван Стеценко: ЯП Zephir. Панацея или лечение?
Oleg Poludnenko
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Sergey Platonov
 
Scala performance под капотом
Scala performance под капотомScala performance под капотом
Scala performance под капотом
Roman Grebennikov
 
Python и Cython
Python и CythonPython и Cython
Python и Cython
Alexander Shigin
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++
Sergey Platonov
 
С одним плюсом (Андрей Аксёнов)
С одним плюсом (Андрей Аксёнов)С одним плюсом (Андрей Аксёнов)
С одним плюсом (Андрей Аксёнов)
Unigine Corp.
 
Александр Гладыш — Lua
Александр Гладыш — LuaАлександр Гладыш — Lua
Александр Гладыш — Lua
Yury Yurevich
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
Sergey Platonov
 

What's hot (20)

Rubinius: Ruby написанный на Ruby
Rubinius: Ruby написанный на RubyRubinius: Ruby написанный на Ruby
Rubinius: Ruby написанный на Ruby
 
Павел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладкаПавел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладка
 
Scala: что, как и зачем?
Scala: что, как и зачем?Scala: что, как и зачем?
Scala: что, как и зачем?
 
Scala для всех (РИФ 2015)
Scala для всех (РИФ 2015)Scala для всех (РИФ 2015)
Scala для всех (РИФ 2015)
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализация
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
 
JPHP - О проекте на простом языке
JPHP - О проекте на простом языкеJPHP - О проекте на простом языке
JPHP - О проекте на простом языке
 
DLR Hosting
DLR HostingDLR Hosting
DLR Hosting
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?
 
Эффективный C++
Эффективный C++Эффективный C++
Эффективный C++
 
Михаил Давыдов: JavaScript. Базовые знания
Михаил Давыдов: JavaScript. Базовые знанияМихаил Давыдов: JavaScript. Базовые знания
Михаил Давыдов: JavaScript. Базовые знания
 
Иван Стеценко: ЯП Zephir. Панацея или лечение?
Иван Стеценко: ЯП Zephir. Панацея или лечение?Иван Стеценко: ЯП Zephir. Панацея или лечение?
Иван Стеценко: ЯП Zephir. Панацея или лечение?
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
 
Scala performance под капотом
Scala performance под капотомScala performance под капотом
Scala performance под капотом
 
JavaScript Intro
JavaScript IntroJavaScript Intro
JavaScript Intro
 
Python и Cython
Python и CythonPython и Cython
Python и Cython
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++
 
С одним плюсом (Андрей Аксёнов)
С одним плюсом (Андрей Аксёнов)С одним плюсом (Андрей Аксёнов)
С одним плюсом (Андрей Аксёнов)
 
Александр Гладыш — Lua
Александр Гладыш — LuaАлександр Гладыш — Lua
Александр Гладыш — Lua
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
 

Similar to Alexander Dymo - IT-клуб Николаева - April 2011 - Ruby: Beaty and the Beast

About Python
About PythonAbout Python
About Python
Yury Yurevich
 
Ruby - или зачем мне еще один язык программирования?
Ruby - или зачем мне еще один язык программирования?Ruby - или зачем мне еще один язык программирования?
Ruby - или зачем мне еще один язык программирования?
Pavel Tsukanov
 
Groovy presentation on Exception #7 conference
Groovy presentation on Exception #7 conferenceGroovy presentation on Exception #7 conference
Groovy presentation on Exception #7 conference
voituk
 
Rupyru2007 Rastyagaev Ruby
Rupyru2007 Rastyagaev RubyRupyru2007 Rastyagaev Ruby
Rupyru2007 Rastyagaev Rubyemarkine
 
Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013ScalaNsk
 
Системное тестирование приложений на Ruby on Rails с применением Rspec и Cap...
Системное тестирование  приложений на Ruby on Rails с применением Rspec и Cap...Системное тестирование  приложений на Ruby on Rails с применением Rspec и Cap...
Системное тестирование приложений на Ruby on Rails с применением Rspec и Cap...lshevtsov
 
Golang в действии: Как нам удается писать highload приложение на (не?)подходя...
Golang в действии: Как нам удается писать highload приложение на (не?)подходя...Golang в действии: Как нам удается писать highload приложение на (не?)подходя...
Golang в действии: Как нам удается писать highload приложение на (не?)подходя...
Daniel Podolsky
 
Опыт разработки и тестирования RESTful JSON сервиса
Опыт разработки и тестирования RESTful JSON сервисаОпыт разработки и тестирования RESTful JSON сервиса
Опыт разработки и тестирования RESTful JSON сервиса
Ilya Chesnokov
 
Saint Perl 2009: CGI::Ajax demo
Saint Perl 2009: CGI::Ajax demoSaint Perl 2009: CGI::Ajax demo
Saint Perl 2009: CGI::Ajax demo
megakott
 
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...
DevPoint Kyiv
 
CodeFest 2012. Сидельников А. — Опыт создания DSL на Ruby. Где применить, как...
CodeFest 2012. Сидельников А. — Опыт создания DSL на Ruby. Где применить, как...CodeFest 2012. Сидельников А. — Опыт создания DSL на Ruby. Где применить, как...
CodeFest 2012. Сидельников А. — Опыт создания DSL на Ruby. Где применить, как...CodeFest
 
ZFConf 2010: Zend Framework and Multilingual
ZFConf 2010: Zend Framework and MultilingualZFConf 2010: Zend Framework and Multilingual
ZFConf 2010: Zend Framework and MultilingualZFConf Conference
 
Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"
Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"
Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"
QA Dnepropetrovsk Community (Ukraine)
 
Enter: legacy code
Enter: legacy codeEnter: legacy code
Enter: legacy code
Kamil Samigullin
 
Solit 2014, Минусы ООП на примере языка PHP, Соловей Василий
Solit 2014, Минусы ООП на примере языка PHP, Соловей ВасилийSolit 2014, Минусы ООП на примере языка PHP, Соловей Василий
Solit 2014, Минусы ООП на примере языка PHP, Соловей Василий
solit
 

Similar to Alexander Dymo - IT-клуб Николаева - April 2011 - Ruby: Beaty and the Beast (20)

python vs ruby
python vs rubypython vs ruby
python vs ruby
 
About Python
About PythonAbout Python
About Python
 
Ruby - или зачем мне еще один язык программирования?
Ruby - или зачем мне еще один язык программирования?Ruby - или зачем мне еще один язык программирования?
Ruby - или зачем мне еще один язык программирования?
 
Groovy presentation on Exception #7 conference
Groovy presentation on Exception #7 conferenceGroovy presentation on Exception #7 conference
Groovy presentation on Exception #7 conference
 
Rupyru2007 Rastyagaev Ruby
Rupyru2007 Rastyagaev RubyRupyru2007 Rastyagaev Ruby
Rupyru2007 Rastyagaev Ruby
 
Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013
 
бегун
бегунбегун
бегун
 
бегун
бегунбегун
бегун
 
php frameworks
php frameworksphp frameworks
php frameworks
 
Системное тестирование приложений на Ruby on Rails с применением Rspec и Cap...
Системное тестирование  приложений на Ruby on Rails с применением Rspec и Cap...Системное тестирование  приложений на Ruby on Rails с применением Rspec и Cap...
Системное тестирование приложений на Ruby on Rails с применением Rspec и Cap...
 
Golang в действии: Как нам удается писать highload приложение на (не?)подходя...
Golang в действии: Как нам удается писать highload приложение на (не?)подходя...Golang в действии: Как нам удается писать highload приложение на (не?)подходя...
Golang в действии: Как нам удается писать highload приложение на (не?)подходя...
 
Ruby exceptions
Ruby exceptionsRuby exceptions
Ruby exceptions
 
Опыт разработки и тестирования RESTful JSON сервиса
Опыт разработки и тестирования RESTful JSON сервисаОпыт разработки и тестирования RESTful JSON сервиса
Опыт разработки и тестирования RESTful JSON сервиса
 
Saint Perl 2009: CGI::Ajax demo
Saint Perl 2009: CGI::Ajax demoSaint Perl 2009: CGI::Ajax demo
Saint Perl 2009: CGI::Ajax demo
 
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...
 
CodeFest 2012. Сидельников А. — Опыт создания DSL на Ruby. Где применить, как...
CodeFest 2012. Сидельников А. — Опыт создания DSL на Ruby. Где применить, как...CodeFest 2012. Сидельников А. — Опыт создания DSL на Ruby. Где применить, как...
CodeFest 2012. Сидельников А. — Опыт создания DSL на Ruby. Где применить, как...
 
ZFConf 2010: Zend Framework and Multilingual
ZFConf 2010: Zend Framework and MultilingualZFConf 2010: Zend Framework and Multilingual
ZFConf 2010: Zend Framework and Multilingual
 
Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"
Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"
Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"
 
Enter: legacy code
Enter: legacy codeEnter: legacy code
Enter: legacy code
 
Solit 2014, Минусы ООП на примере языка PHP, Соловей Василий
Solit 2014, Минусы ООП на примере языка PHP, Соловей ВасилийSolit 2014, Минусы ООП на примере языка PHP, Соловей Василий
Solit 2014, Минусы ООП на примере языка PHP, Соловей Василий
 

Alexander Dymo - IT-клуб Николаева - April 2011 - Ruby: Beaty and the Beast

  • 1. Ruby: Beauty and the Beast Александр Дымо IT-клуб Николаева www.acunote.com
  • 2.
  • 3. 29 000 строк кода
  • 4. 45 500 строк тестов
  • 6.
  • 8.
  • 9.
  • 12.
  • 13. Язык Ruby: Что понравилось Меньше кода – больше кислорода! ~3-4 разработчика * ~5 лет = 29k строк???
  • 14. Язык Ruby: Что понравилось Меньше кода – больше кислорода! 400 строк на Ruby == 6000 на C++
  • 15. Язык Ruby: Что понравилось Уж больно хорошо все выглядит! module SearchLanguage class Parser class ParseError < StandardError; end def self. parse (text) parser = Parser. new parser. parse (text) end private : def parse_search_query parse_and_expression end def parse_and_expression match_spaces node = ExpressionNode. new (:and) return node if empty_buffer? node. expressions << parse_or_expression while match_AND and !empty_buffer? and !end_of_subexpression? node. expressions << parse_or_expression end node end end end
  • 16. Язык Ruby: Что понравилось Методы с ! и ? [1,2,3] . include? 2 &quot;foo bar&quot; . gsub ( &quot;o&quot; , &quot;a&quot; ) &quot;foo bar&quot; . gsub! ( &quot;o&quot; , &quot;a&quot; )
  • 17. Язык Ruby: Что понравилось Методы с ! и ? class Foo def transform! #... end def transformed? #... end end
  • 18. Язык Ruby: Что понравилось Элегантный подход к getters/setters class Foo attr_accessor :foo end class Foo def foo @foo end def foo=(value) @foo = value end end f = Foo.new f.foo = 2 # f.foo=(2) puts f.foo
  • 19. Язык Ruby: Что понравилось Блоки def do_smth(&block) puts yield(10) puts yield(20) end do_smth { |value| value + 5 } > 15 > 25
  • 20. Язык Ruby: Что понравилось Возможность встроиться куда угодно class Time def humanize strftime(&quot;%a %b %d, %Y %H:%M&quot;) end end puts Time.now.humanize > Thu Apr 21, 2011 13:37 ...мы дополнили 28 различных классов
  • 21. Язык Ruby: Что понравилось Возможность встроиться куда угодно class BigDecimal alias_method :eq_without_boolean_comparison, :== def eq_with_boolean_comparison(other) if [FalseClass, TrueClass].include? other.class return false end eq_without_boolean_comparison(other) end alias_method :==, :eq_with_boolean_comparison end
  • 22. Язык Ruby: Что понравилось Правильный способ встраивания/расширения class Foo def do_smth puts &quot;Hello World&quot; end end class Foo def do_smth_with_decoration puts &quot;--------------&quot; do_smth_without_decoration puts &quot;--------------&quot; end end f = Foo.new f.do_smth > -------------- > Hello World > --------------
  • 23. Язык Ruby: Что понравилось Возможность переписать все что угодно class Foo { private: void doSmth() { std::cout << &quot;Hello World&quot; } }; ... class Foo def doSmth puts &quot;Hi&quot; end end f = Foo.new f.doSmth > Hi
  • 24.
  • 26.
  • 27.
  • 30.
  • 31. Язык Ruby: Что не понравилось Perl'измы в синтаксисе x = false or true puts x #???
  • 32. Язык Ruby: Что не понравилось Perl'измы в синтаксисе x = false or true (x = false) or true puts x > false
  • 33. Язык Ruby: Что не понравилось Perl'измы в синтаксисе x = false || true x = (false || true) puts x > true
  • 34. Язык Ruby: Что не понравилось Perl'измы в синтаксисе x = 2 if false or true puts x > ?
  • 35. Язык Ruby: Что не понравилось Perl'измы в синтаксисе x = 2 if false or true x = 2 if (false or true) puts x > 2
  • 36. Язык Ruby: Что не понравилось Python'измы в синтаксисе class Foo attr_accessor :x def do_smth x = 10 end end f = Foo.new f.x > nil #WTF?
  • 37. Язык Ruby: Что не понравилось Python'измы в синтаксисе class Foo attr_accessor :x def do_smth self. x = 10 end end f = Foo.new f.x > 10
  • 38. Язык Ruby: Что не понравилось Переменные экземпляров классов class Foo attr_accessor :x def initialize @x = 10 #или self.x = 10 y = @x #или y = x end end
  • 39.
  • 41.
  • 42.
  • 45.
  • 46. Язык Ruby: Интересные особенности Модули: пространства имен или решение проблемы множественного наследования module ActiveRecord module ConnectionAdapters class MysqlAdapter def execute #... end end end end module ActiveRecord module Validations def valid? errors.empty? end end class Base include Validations end end
  • 47. Язык Ruby: Интересные особенности Блоки: передача функций в другие функции или предусловия/постусловия def calculate(&algorithm) yield (2, 2) end result = calculate do |x,y| x + y end def calculate(&expression) return unless can_calculate? result = yield result.good? ? result : nil end result = calculate do 2+2 end
  • 48. Язык Ruby: Интересные особенности method_missing class GoldenFish def method_missing(name, *args, &block) if name == :make_me_rich puts &quot;here you go: $1 000 000&quot; else puts &quot;you want too much!&quot; end end end fish = GoldenFish.new fish.make_me_rich > here you go: $1 000 000 fish.make_my_old_wife_a_supermodel > you want too much!
  • 49. Язык Ruby: Интересные особенности Ассоциации в Rails: реализация с method_missing class User has_many :roles end user = User.find(:first) #метод ассоциации user.roles.find(:all, :conditions => &quot;name = 'Admin'&quot;) #метод массива user.roles.map { |role| role.name }
  • 50. Язык Ruby: Интересные особенности Ассоциации в Rails: реализация с method_missing class AssociationProxy def reload @target = [1,2,3] #just for an example end def method_missing(method, *args, &block) if @target.respond_to? method @target.send(method, *args, &block) else raise NoMethodError end end end end p = AssociationProxy.new p.reload #вызываем свой метод p << 3 #вызываем метод класса Array (у @target)
  • 51.
  • 53.
  • 54.
  • 57.
  • 58. Ruby Runtime: Что с ним так и не так
  • 59. Ruby Runtime: Что с ним так и не так Ruby – это красиво, удобно, мощно... но где же подвох?
  • 60. Ruby Runtime: Что с ним так и не так Ruby – это медленно !
  • 61. Ruby Runtime: Что с ним так и не так Ruby – это очень медленно !
  • 62. Ruby Runtime: Что с ним так и не так Апрель 2008 Май 2008 Июнь 2008 Июль 2008 Время обслуживания запроса, % Худший случай: O(n a ) В среднем: O(log n)
  • 63.
  • 65.
  • 66.
  • 69.
  • 70. Ruby Runtime: Garbage Collection Сборка мусора – самое плохое что может произойти с вашим Ruby кодом!
  • 71. Ruby Runtime: Garbage Collection Сборка мусора происходит: каждые 8 Мб выделенной памяти выделенная однажды память повторно используется но никогда не возвращается!
  • 72. Ruby Runtime: Garbage Collection в среднем приложении 1 сборка мусора == 100ms выделяете 1Gb? - ожидайте 1024/8 = 128 вызовов GC - потеряете 128 * 0,1 = 12,8 sec!!! - навсегда оставите себе этот гиг
  • 73. Ruby Runtime: Garbage Collection class TestController def index gc_statistics { #дайте-ка мне гиг памяти! 1024.times { &quot;x&quot;*1024*1024 } } end end app.get '/test' > : allocated: 1049602K total in 2052 allocations, GC calls: 146, GC time: 17281 msec
  • 74. Ruby Runtime: Garbage Collection Патч, включающий сбор статистики про GC http://blog.pluron.com/2008/02/memory-profilin.html
  • 75. Ruby Runtime: Garbage Collection Эффект сборки мусора: GC GC Area Burndown 120 0,94 0,65 1,5x Sprint 20 x (1+5) (C) 0,59 0,30 2,0x Sprint 20 x (1+5) 0,70 0,40 1,8x Move Left 0,77 0,46 1,7x Ruby приложение будет в 2 раза медленнее! &quot;Спасибо&quot; сборщику мусора!
  • 76. Ruby Runtime: Garbage Collection Способы бороться с GC в Ruby Enterprise Edition (www.rubyenterpriseedition.com) по-умолчанию RUBY_HEAP_MIN_SLOTS=10000 RUBY_HEAP_SLOTS_INCREMENT=10000 RUBY_GC_MALLOC_LIMIT=8000000 RUBY_HEAP_SLOTS_GROWTH_FACTOR=1.8 оптимальные настройки надо подбирать, но примерно RUBY_HEAP_MIN_SLOTS=1250000 RUBY_HEAP_SLOTS_INCREMENT=100000 RUBY_GC_MALLOC_LIMIT=30000000 RUBY_HEAP_SLOTS_GROWTH_FACTOR=1
  • 77. Ruby Runtime: Garbage Collection Альтернативы? JRuby
  • 78. Ruby Runtime: Garbage Collection Альтернативы? кто хочет написать generational garbage collector для Ruby?
  • 79.
  • 81.
  • 82.
  • 85.
  • 86.
  • 87. Инструменты: Редакторы и IDE Ruby – проклятье разработчиков IDE def foo(arg) arg. end foo(2) foo(Class.new)
  • 88. Инструменты: Редакторы и IDE Ruby – проклятье разработчиков IDE class Foo 10.times do |i| define_method &quot;great_method_#{i}&quot; .to_sym do #... end end end f = Foo.new f.
  • 89.
  • 91.
  • 92.
  • 95.
  • 96. Инструменты: Тестирование TDD/BDD: Test::Unit, RSpec, Cucumber, etc. Continuous Integration: CruiseControl (http://cruisecontrol.sourceforge.net/)
  • 97. Инструменты: Тестирование Не спешите выбрасывать Test::Unit, он еще послужит Обычно тестируют так: def test_file_tree tree = FilesTree.new( &quot;/home/user&quot; ) assert tree assert_equal &quot;.&quot; , tree[0], assert_equal &quot;..&quot; , tree[1], assert_equal &quot;dir1&quot; , tree[2] assert_equal &quot;file1&quot; , tree[2][0] assert_equal &quot;file2&quot; , tree[3] end
  • 98. Инструменты: Тестирование Не спешите выбрасывать Test::Unit, он еще послужит: мечтают о таком (cucumber) scenario : sample file tree When I go to /home/user Then I see current directory, top directory, dir1 There's a file2 in current directory There's a file1 in dir1 directory end
  • 99. Инструменты: Тестирование Не спешите выбрасывать Test::Unit, он еще послужит: но лучше всего так (Test::Unit): def test_file_tree tree = FilesTree.new( &quot;/home/user&quot; ) assert_equal serialize_tree(tree), <<-END . .. dir1 file1 file2 END end
  • 100.
  • 102.
  • 103.
  • 106.
  • 107. Инструменты: Производительность Медленный Ruby Что делать? Профилировать с Ruby-Prof Переписывать на C Переписывать на SQL
  • 108. Инструменты: Производительность Ruby-Prof (http://ruby-prof.rubyforge.org/) Всегда скажет что не так: %self total self child calls name 8.39 0.54 0.23 0.31 602 Array#each_index 7.30 0.41 0.20 0.21 1227 Integer#gcd 6.20 0.49 0.17 0.32 5760 Timecell#date 5.11 0.15 0.14 0.01 1 Magick::Image#to_blob gem install ruby-prof KCachegrind для визуализации результатов http://kcachegrind.sourceforge.net
  • 110. Инструменты: Производительность До какой степени оптимизировать? Пока не будет так: %self total self child calls name 1.42 0.39 0.25 0.14 1033 Range#each-1 0.85 0.43 0.15 0.28 2221 Array#each-1 0.74 0.13 0.13 0.00 113447 Array#[] 0.40 0.07 0.07 0.00 5008 Hash#initialize_copy 0.40 0.07 0.07 0.00 45467 Hash#[]= 0.40 0.13 0.07 0.06 37784 Hash#[] 0.17 0.15 0.03 0.12 176 Array#collect 0.17 0.08 0.03 0.05 22371 String#gsub 0.17 0.03 0.03 0.00 44881 Array#<< 0.17 0.03 0.03 0.00 15936 String#== 0.17 0.75 0.03 0.72 1218 Array#each 0.17 0.03 0.03 0.00 37274 PGresult#getvalue 0.11 0.18 0.02 0.16 137 Array#collect! 0.11 0.02 0.02 0.00 3227 User#id
  • 111. Инструменты: Производительность Что нужно помнить при профилировке Ruby приложений? не забывать профилировать память в среднем приложении 1 сборка мусора == 100ms выделяете 1Gb? - ожидайте 1024/8 = 128 вызовов GC - потеряете 128 * 0,1 = 12,8 sec!!!
  • 112. Инструменты: Производительность Что нужно помнить при профилировке Ruby приложений? выключать GC (GC.disable), иначе можно увидеть: class Foo def do_smth return &quot;x&quot; * 1024 # займем 1Kb памяти end end smth = &quot;x&quot; * 7999999 # займем почти 8Mb памяти Foo.new.do_smth # здесь произойдет GC -------------------------- %self calls name 0.10 1 Foo#do_smth # do_smth такой медленный??? 0.01 2 String#*
  • 113. Инструменты: Производительность Переписывать на C не такая уж плохая идея: date-performance github.com/rtomayko/date-performance ускоряет операции с датами в 13 раз! ускоряет приложения в 1.5 раза monkeysupport http://github.com/burke/monkeysupport ActiveSupport переписанный на C
  • 114. Инструменты: Производительность Переписывать Rails приложение на SQL тоже неплохая идея: – иногда ускорение в 5х – иногда делает возможным то, что невозможно в Ruby операции над большим кол-вом (1млн) объектов – детали в моей презентации &quot;Быстрее, Выше, SQL'нее&quot; http://www.slideshare.net/adymo/alexander-dymo-barcamp-2009-faster-higher-sql-2644467
  • 115. Инструменты: Производительность Почему все так плохо? нет реальных приложений, на которых Ruby (и Rails) core teams могли бы тестировать производительность некому написать generational GC никто не профилирует память
  • 116.
  • 118.
  • 119.
  • 122.
  • 123. Инструменты: Деплоймент monit скрипты мониторинга Отличительные особенности: - скорость ограничена CPU - нужно много памяти VPS'ы могут не подходить! Хорошо работает - capistrano - rinda unicorn unicorn unicorn unicorn unicorn nginx rinda (s) rinda (w)
  • 124.
  • 126.
  • 127.
  • 130.
  • 132. Какой Ruby выбрать? Производительность различных версий Ruby, %
  • 133. Спасибо за внимание! Александр Дымо Director of Engineering [email_address]

Editor's Notes

  1. scrum, Тим Евграшин
  2. 5-7 строк в день на человека
  3. однострочные декларации необязательный return читабельность знакомый синтаксис (нет культурного шока) символы