SlideShare ist ein Scribd-Unternehmen logo
1 von 22
Беспокойный код
    @SergeyMoiseev
О себе


• Девелопер с 1998 года.
• Писал индустриальные системы на PHP.
• Теперь на RoR.
Как определить
        неофита?

• Толстые контроллеры
• Беспокойство
• Желание “работать” с предельными
  условиями
Самый простой
   способ?
  def   foobar
    x   = self.bar
    x   = nil if x == 0
    y   = foo

    return x || y
  end
Return

• Самый неочевидный оператор для
  новичков
• Функция его наиболее отличается от
  таковой в других языках
return для flow-control
    def foobar
      if foo?
        if bar?
           #do something
           return 42
        else
           #do something
        end
      else
        #do something
      end
    end
if || unless
           if !params[:query].blank?




if !something                  unless something
unless?

• Как ни странно, это единственное для
  чего он нужен.
• Читать логику объединенную and/or при
  этом применяя к ней ! сложно.
• У него нет elsunless (нельзя сказать, что
  это минус).
If/else vs. unless
def possible_parents
  if self.new_record?
    Category.first_level
  else
    Category.first_level.where('id != ?', self.id)
  end
end

                                 vs.

   scope :not_given, lambda{|id| where('id != ?', id)}

   def possible_parents
     Category.first_level
     Category.first_level.not_given(self.id) unless self.new_record?
   end
Виды беспокойства

• Боязнь пользователя (глупого или
  злонамерянного).
• Боязнь предельных условий.
• Боязнь языка. Недостаток времени для
  экспериментов.
• Иллюзия контроля.
Боязнь пользователя
          Код из контроллера в админке
@role = Role.find params[:id]
redirect_to role_index_path and return unless @role


  Программист боится неправильного параметра.
 При этом он забывает о том, что find выбрасывает
                   exception.
Боязнь предельных
             условий
session[:foo] = params[:foo].blank? ? nil :
params[:foo].to_i


                         VS.

session[:foo] = params[:foo] ? params[:foo] : nil
Боязнь языка
scope :with_state, lambda {|state| where('state = ?',
state.to_s)}
scope :ready_for_start, with_state(:foo)
scope :ready_for_close, where('state IN(?)',
[:foo, :bar])


     “А вдруг он не приведет символ к строке?”

scope :with_states, lambda {|s| where("state in
(#{s.map{|e| "'#{e.to_s}'"}.join(',')})")}
Иллюзия контроля
def self.find_for_facebook_oauth(access_token,
signed_in_resource=nil)
  data = access_token['extra']['user_hash']
  if user = User.find_by_email(data["email"])
    user
  else # Create a user with a stub password.
    user = User.create do |record|
      record.email = data['email']
      record.password = Devise.friendly_token[0,20]
      record.registration_source = 1
      record.skip_confirmation!
    end
  end
end
Ослепление
          беспокойством

def self.to_rtf(codes)
  buffer = ""
  codes.each {|code| buffer << code.value << "n"}
  buffer
end
Ослепление
            беспокойством 2
def self.to_rtf(codes)
  codes.inject("") {|code, buffer| buffer << code.value << "n"}
end



                    Это был рефакторинг
Ослепление
   беспокойством 3
   def self.to_rtf(codes)
     codes.map(&:value).join("n")
   end

А это то, что на самом деле было нужно.
Знай свои
              инструменты
before_filter :guests_only!

def guests_only!
  redirect_to root_url and return if user_signed_in?
end

                 Зачем тут return?
Разгадка
• Программист не знает, как работает
  before_filter.
• Он беспокоится, что код контроллера
  будет выполняться после редиректа в
  фильтре.
• От своего беспокойства он забывает как
  о том, что нужно возвращать false, так и о
  том, что после редиректа это уже лишнее.
Более простое
       объяснение

• Код был перенесен в фильтр из экшена.
• Программисту просто не хочется его
  переписывать, потому как кажется, что
  этот возврат нужен (возвращаемся к
  исходному объяснению).
Metaprogramming to
          the recsue
if permission.can?
  can permission.action.to_sym, subject
else
  cannot permission.action.to_sym, subject
end


                    vs.
     method = permission.can? ? :can : :cannot
     send method, permission.action.to_sym, subject
Способы борьбы


• Знание языка
• Критический взгляд на свой код
• Let it fail (hoptoad в помощь)

Weitere ähnliche Inhalte

Andere mochten auch

حل معادلة باكمال مربع
حل معادلة باكمال مربعحل معادلة باكمال مربع
حل معادلة باكمال مربعDina Zaghdad
 
Trabajo de photo filtre nº 2
Trabajo de photo filtre nº 2Trabajo de photo filtre nº 2
Trabajo de photo filtre nº 2Jorge Muñiz
 
El inicio de la independencia-1
El inicio de la independencia-1El inicio de la independencia-1
El inicio de la independencia-1pefo
 
Picnic for 24contest2 @ Cookpad
Picnic for 24contest2 @ CookpadPicnic for 24contest2 @ Cookpad
Picnic for 24contest2 @ CookpadR. Ayakix
 
TIM KHOẺ VỚI DẦU OLIVE TINH KHIẾT - VUI TRẺ KHỎE.COM
TIM KHOẺ VỚI DẦU OLIVE TINH KHIẾT - VUI TRẺ KHỎE.COMTIM KHOẺ VỚI DẦU OLIVE TINH KHIẾT - VUI TRẺ KHỎE.COM
TIM KHOẺ VỚI DẦU OLIVE TINH KHIẾT - VUI TRẺ KHỎE.COMvunangluong
 
中国网上零售商城品牌50强
中国网上零售商城品牌50强中国网上零售商城品牌50强
中国网上零售商城品牌50强Mingbao Ying
 
Termodinamika2
Termodinamika2Termodinamika2
Termodinamika2rossanty
 
Rinnovo automatico
Rinnovo automaticoRinnovo automatico
Rinnovo automaticoRegister.it
 
华惹》时代风云新书推介礼
华惹》时代风云新书推介礼华惹》时代风云新书推介礼
华惹》时代风云新书推介礼pkkjohor
 
Power derivades 2
Power derivades 2Power derivades 2
Power derivades 2adepares
 
цахим тестэ
цахим тестэцахим тестэ
цахим тестэDash Oogii
 
韓国の社会的企業から学ぶ 雇用開発のあり方
韓国の社会的企業から学ぶ雇用開発のあり方韓国の社会的企業から学ぶ雇用開発のあり方
韓国の社会的企業から学ぶ 雇用開発のあり方Takuji Hiroishi
 

Andere mochten auch (20)

шоколад и дерево
шоколад и деревошоколад и дерево
шоколад и дерево
 
حل معادلة باكمال مربع
حل معادلة باكمال مربعحل معادلة باكمال مربع
حل معادلة باكمال مربع
 
Trabajo de photo filtre nº 2
Trabajo de photo filtre nº 2Trabajo de photo filtre nº 2
Trabajo de photo filtre nº 2
 
El inicio de la independencia-1
El inicio de la independencia-1El inicio de la independencia-1
El inicio de la independencia-1
 
Picnic for 24contest2 @ Cookpad
Picnic for 24contest2 @ CookpadPicnic for 24contest2 @ Cookpad
Picnic for 24contest2 @ Cookpad
 
V 266
V 266V 266
V 266
 
1 číslo tsl
1 číslo tsl1 číslo tsl
1 číslo tsl
 
TIM KHOẺ VỚI DẦU OLIVE TINH KHIẾT - VUI TRẺ KHỎE.COM
TIM KHOẺ VỚI DẦU OLIVE TINH KHIẾT - VUI TRẺ KHỎE.COMTIM KHOẺ VỚI DẦU OLIVE TINH KHIẾT - VUI TRẺ KHỎE.COM
TIM KHOẺ VỚI DẦU OLIVE TINH KHIẾT - VUI TRẺ KHỎE.COM
 
Usa経済指標0518
Usa経済指標0518Usa経済指標0518
Usa経済指標0518
 
中国网上零售商城品牌50强
中国网上零售商城品牌50强中国网上零售商城品牌50强
中国网上零售商城品牌50强
 
Cirsoc 105
Cirsoc 105Cirsoc 105
Cirsoc 105
 
Termodinamika2
Termodinamika2Termodinamika2
Termodinamika2
 
Praia Abrigo
Praia AbrigoPraia Abrigo
Praia Abrigo
 
Rinnovo automatico
Rinnovo automaticoRinnovo automatico
Rinnovo automatico
 
华惹》时代风云新书推介礼
华惹》时代风云新书推介礼华惹》时代风云新书推介礼
华惹》时代风云新书推介礼
 
Power derivades 2
Power derivades 2Power derivades 2
Power derivades 2
 
цахим тестэ
цахим тестэцахим тестэ
цахим тестэ
 
Bertrand Russell
Bertrand RussellBertrand Russell
Bertrand Russell
 
Life
LifeLife
Life
 
韓国の社会的企業から学ぶ 雇用開発のあり方
韓国の社会的企業から学ぶ雇用開発のあり方韓国の社会的企業から学ぶ雇用開発のあり方
韓国の社会的企業から学ぶ 雇用開発のあり方
 

Ähnlich wie Worried code

Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The Beast
Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The BeastAlexander Dymo - IT Jam 2009 - Ruby: Beaty Or The Beast
Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The BeastAlexander Dymo
 
Программирование как способ выражения мыслей.
Программирование как способ выражения мыслей. Программирование как способ выражения мыслей.
Программирование как способ выражения мыслей. Levon Avakyan
 
Alexander Dymo - IT-клуб Николаева - April 2011 - Ruby: Beaty and the Beast
Alexander Dymo - IT-клуб Николаева - April 2011 - Ruby: Beaty and the BeastAlexander Dymo - IT-клуб Николаева - April 2011 - Ruby: Beaty and the Beast
Alexander Dymo - IT-клуб Николаева - April 2011 - Ruby: Beaty and the BeastAlexander Dymo
 
Теории и практики функционального программирования.
Теории и практики функционального программирования.Теории и практики функционального программирования.
Теории и практики функционального программирования.Dev2Dev
 
Теории и практики фунционального программирования - GDG D2D
Теории и практики фунционального программирования - GDG D2DТеории и практики фунционального программирования - GDG D2D
Теории и практики фунционального программирования - GDG D2D0xffAA
 
Grail - CodeFest'2015
Grail - CodeFest'2015Grail - CodeFest'2015
Grail - CodeFest'2015Igor Khrol
 
Grail: шаги для ваших Python-тестов
Grail: шаги для ваших Python-тестовGrail: шаги для ваших Python-тестов
Grail: шаги для ваших Python-тестовCodeFest
 
Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013ScalaNsk
 
Algorithms and programming lecture in ru
Algorithms and programming lecture in ruAlgorithms and programming lecture in ru
Algorithms and programming lecture in russuser0562f1
 
Алгоритмизация и программирование С/С++
Алгоритмизация и  программирование С/С++Алгоритмизация и  программирование С/С++
Алгоритмизация и программирование С/С++ssuser0562f1
 
Демонизированный PHP - before it was cool
Демонизированный PHP - before it was coolДемонизированный PHP - before it was cool
Демонизированный PHP - before it was coolAndrey Tokarchuk
 
functional patterns - dotnetconf'11
functional patterns - dotnetconf'11functional patterns - dotnetconf'11
functional patterns - dotnetconf'110xffAA
 
Андрей Карпов, Приватные байки от разработчиков анализатора кода
Андрей Карпов, Приватные байки от разработчиков анализатора кодаАндрей Карпов, Приватные байки от разработчиков анализатора кода
Андрей Карпов, Приватные байки от разработчиков анализатора кодаSergey Platonov
 
Лекция 1. Начало.
Лекция 1. Начало.Лекция 1. Начало.
Лекция 1. Начало.Roman Brovko
 
2015-03-07 03 Сергей Александрович. 50 оттенков красного
2015-03-07 03 Сергей Александрович. 50 оттенков красного2015-03-07 03 Сергей Александрович. 50 оттенков красного
2015-03-07 03 Сергей Александрович. 50 оттенков красногоОмские ИТ-субботники
 
Лекция 6. Классы 1.
Лекция 6. Классы 1.Лекция 6. Классы 1.
Лекция 6. Классы 1.Roman Brovko
 

Ähnlich wie Worried code (20)

Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The Beast
Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The BeastAlexander Dymo - IT Jam 2009 - Ruby: Beaty Or The Beast
Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The Beast
 
About Python
About PythonAbout Python
About Python
 
Enter: legacy code
Enter: legacy codeEnter: legacy code
Enter: legacy code
 
Программирование как способ выражения мыслей.
Программирование как способ выражения мыслей. Программирование как способ выражения мыслей.
Программирование как способ выражения мыслей.
 
Alexander Dymo - IT-клуб Николаева - April 2011 - Ruby: Beaty and the Beast
Alexander Dymo - IT-клуб Николаева - April 2011 - Ruby: Beaty and the BeastAlexander Dymo - IT-клуб Николаева - April 2011 - Ruby: Beaty and the Beast
Alexander Dymo - IT-клуб Николаева - April 2011 - Ruby: Beaty and the Beast
 
Теории и практики функционального программирования.
Теории и практики функционального программирования.Теории и практики функционального программирования.
Теории и практики функционального программирования.
 
Теории и практики фунционального программирования - GDG D2D
Теории и практики фунционального программирования - GDG D2DТеории и практики фунционального программирования - GDG D2D
Теории и практики фунционального программирования - GDG D2D
 
Grail - CodeFest'2015
Grail - CodeFest'2015Grail - CodeFest'2015
Grail - CodeFest'2015
 
Grail: шаги для ваших Python-тестов
Grail: шаги для ваших Python-тестовGrail: шаги для ваших Python-тестов
Grail: шаги для ваших Python-тестов
 
Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013
 
Algorithms and programming lecture in ru
Algorithms and programming lecture in ruAlgorithms and programming lecture in ru
Algorithms and programming lecture in ru
 
Алгоритмизация и программирование С/С++
Алгоритмизация и  программирование С/С++Алгоритмизация и  программирование С/С++
Алгоритмизация и программирование С/С++
 
Ruby exceptions
Ruby exceptionsRuby exceptions
Ruby exceptions
 
Демонизированный PHP - before it was cool
Демонизированный PHP - before it was coolДемонизированный PHP - before it was cool
Демонизированный PHP - before it was cool
 
functional patterns - dotnetconf'11
functional patterns - dotnetconf'11functional patterns - dotnetconf'11
functional patterns - dotnetconf'11
 
Андрей Карпов, Приватные байки от разработчиков анализатора кода
Андрей Карпов, Приватные байки от разработчиков анализатора кодаАндрей Карпов, Приватные байки от разработчиков анализатора кода
Андрей Карпов, Приватные байки от разработчиков анализатора кода
 
Лекция 1. Начало.
Лекция 1. Начало.Лекция 1. Начало.
Лекция 1. Начало.
 
2015-03-07 03 Сергей Александрович. 50 оттенков красного
2015-03-07 03 Сергей Александрович. 50 оттенков красного2015-03-07 03 Сергей Александрович. 50 оттенков красного
2015-03-07 03 Сергей Александрович. 50 оттенков красного
 
50 оттенков красного
50 оттенков красного50 оттенков красного
50 оттенков красного
 
Лекция 6. Классы 1.
Лекция 6. Классы 1.Лекция 6. Классы 1.
Лекция 6. Классы 1.
 

Worried code

  • 2. О себе • Девелопер с 1998 года. • Писал индустриальные системы на PHP. • Теперь на RoR.
  • 3. Как определить неофита? • Толстые контроллеры • Беспокойство • Желание “работать” с предельными условиями
  • 4. Самый простой способ? def foobar x = self.bar x = nil if x == 0 y = foo return x || y end
  • 5. Return • Самый неочевидный оператор для новичков • Функция его наиболее отличается от таковой в других языках
  • 6. return для flow-control def foobar if foo? if bar? #do something return 42 else #do something end else #do something end end
  • 7. if || unless if !params[:query].blank? if !something unless something
  • 8. unless? • Как ни странно, это единственное для чего он нужен. • Читать логику объединенную and/or при этом применяя к ней ! сложно. • У него нет elsunless (нельзя сказать, что это минус).
  • 9. If/else vs. unless def possible_parents if self.new_record? Category.first_level else Category.first_level.where('id != ?', self.id) end end vs. scope :not_given, lambda{|id| where('id != ?', id)} def possible_parents Category.first_level Category.first_level.not_given(self.id) unless self.new_record? end
  • 10. Виды беспокойства • Боязнь пользователя (глупого или злонамерянного). • Боязнь предельных условий. • Боязнь языка. Недостаток времени для экспериментов. • Иллюзия контроля.
  • 11. Боязнь пользователя Код из контроллера в админке @role = Role.find params[:id] redirect_to role_index_path and return unless @role Программист боится неправильного параметра. При этом он забывает о том, что find выбрасывает exception.
  • 12. Боязнь предельных условий session[:foo] = params[:foo].blank? ? nil : params[:foo].to_i VS. session[:foo] = params[:foo] ? params[:foo] : nil
  • 13. Боязнь языка scope :with_state, lambda {|state| where('state = ?', state.to_s)} scope :ready_for_start, with_state(:foo) scope :ready_for_close, where('state IN(?)', [:foo, :bar]) “А вдруг он не приведет символ к строке?” scope :with_states, lambda {|s| where("state in (#{s.map{|e| "'#{e.to_s}'"}.join(',')})")}
  • 14. Иллюзия контроля def self.find_for_facebook_oauth(access_token, signed_in_resource=nil) data = access_token['extra']['user_hash'] if user = User.find_by_email(data["email"]) user else # Create a user with a stub password. user = User.create do |record| record.email = data['email'] record.password = Devise.friendly_token[0,20] record.registration_source = 1 record.skip_confirmation! end end end
  • 15. Ослепление беспокойством def self.to_rtf(codes) buffer = "" codes.each {|code| buffer << code.value << "n"} buffer end
  • 16. Ослепление беспокойством 2 def self.to_rtf(codes) codes.inject("") {|code, buffer| buffer << code.value << "n"} end Это был рефакторинг
  • 17. Ослепление беспокойством 3 def self.to_rtf(codes) codes.map(&:value).join("n") end А это то, что на самом деле было нужно.
  • 18. Знай свои инструменты before_filter :guests_only! def guests_only! redirect_to root_url and return if user_signed_in? end Зачем тут return?
  • 19. Разгадка • Программист не знает, как работает before_filter. • Он беспокоится, что код контроллера будет выполняться после редиректа в фильтре. • От своего беспокойства он забывает как о том, что нужно возвращать false, так и о том, что после редиректа это уже лишнее.
  • 20. Более простое объяснение • Код был перенесен в фильтр из экшена. • Программисту просто не хочется его переписывать, потому как кажется, что этот возврат нужен (возвращаемся к исходному объяснению).
  • 21. Metaprogramming to the recsue if permission.can? can permission.action.to_sym, subject else cannot permission.action.to_sym, subject end vs. method = permission.can? ? :can : :cannot send method, permission.action.to_sym, subject
  • 22. Способы борьбы • Знание языка • Критический взгляд на свой код • Let it fail (hoptoad в помощь)

Hinweis der Redaktion

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n