Беспокойный код    @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  ...
if || unless           if !params[:query].blank?if !something                  unless something
unless?• Как ни странно, это единственное для  чего он нужен.• Читать логику объединенную and/or при  этом применяя к ней ...
If/else vs. unlessdef possible_parents  if self.new_record?    Category.first_level  else    Category.first_level.where(id...
Виды беспокойства• Боязнь пользователя (глупого или  злонамерянного).• Боязнь предельных условий.• Боязнь языка. Недостато...
Боязнь пользователя          Код из контроллера в админке@role = Role.find params[:id]redirect_to role_index_path and retu...
Боязнь предельных             условийsession[:foo] = params[:foo].blank? ? nil :params[:foo].to_i                         ...
Боязнь языкаscope :with_state, lambda {|state| where(state = ?,state.to_s)}scope :ready_for_start, with_state(:foo)scope :...
Иллюзия контроляdef self.find_for_facebook_oauth(access_token,signed_in_resource=nil)  data = access_token[extra][user_has...
Ослепление          беспокойствомdef self.to_rtf(codes)  buffer = ""  codes.each {|code| buffer << code.value << "n"}  buf...
Ослепление            беспокойством 2def self.to_rtf(codes)  codes.inject("") {|code, buffer| buffer << code.value << "n"}...
Ослепление   беспокойством 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_sig...
Разгадка• Программист не знает, как работает  before_filter.• Он беспокоится, что код контроллера  будет выполняться после ...
Более простое       объяснение• Код был перенесен в фильтр из экшена.• Программисту просто не хочется его  переписывать, п...
Metaprogramming to          the recsueif permission.can?  can permission.action.to_sym, subjectelse  cannot permission.act...
Способы борьбы• Знание языка• Критический взгляд на свой код• Let it fail (hoptoad в помощь)
Upcoming SlideShare
Loading in...5
×

Worried code

326

Published on

Slides for my talk on DevConf_ru'11

Published in: Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
326
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
1
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Worried code

    1. 1. Беспокойный код @SergeyMoiseev
    2. 2. О себе• Девелопер с 1998 года.• Писал индустриальные системы на PHP.• Теперь на RoR.
    3. 3. Как определить неофита?• Толстые контроллеры• Беспокойство• Желание “работать” с предельными условиями
    4. 4. Самый простой способ? def foobar x = self.bar x = nil if x == 0 y = foo return x || y end
    5. 5. Return• Самый неочевидный оператор для новичков• Функция его наиболее отличается от таковой в других языках
    6. 6. return для flow-control def foobar if foo? if bar? #do something return 42 else #do something end else #do something end end
    7. 7. if || unless if !params[:query].blank?if !something unless something
    8. 8. unless?• Как ни странно, это единственное для чего он нужен.• Читать логику объединенную and/or при этом применяя к ней ! сложно.• У него нет elsunless (нельзя сказать, что это минус).
    9. 9. If/else vs. unlessdef possible_parents if self.new_record? Category.first_level else Category.first_level.where(id != ?, self.id) endend 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. 10. Виды беспокойства• Боязнь пользователя (глупого или злонамерянного).• Боязнь предельных условий.• Боязнь языка. Недостаток времени для экспериментов.• Иллюзия контроля.
    11. 11. Боязнь пользователя Код из контроллера в админке@role = Role.find params[:id]redirect_to role_index_path and return unless @role Программист боится неправильного параметра. При этом он забывает о том, что find выбрасывает exception.
    12. 12. Боязнь предельных условийsession[:foo] = params[:foo].blank? ? nil :params[:foo].to_i VS.session[:foo] = params[:foo] ? params[:foo] : nil
    13. 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. 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 endend
    15. 15. Ослепление беспокойствомdef self.to_rtf(codes) buffer = "" codes.each {|code| buffer << code.value << "n"} bufferend
    16. 16. Ослепление беспокойством 2def self.to_rtf(codes) codes.inject("") {|code, buffer| buffer << code.value << "n"}end Это был рефакторинг
    17. 17. Ослепление беспокойством 3 def self.to_rtf(codes) codes.map(&:value).join("n") endА это то, что на самом деле было нужно.
    18. 18. Знай свои инструментыbefore_filter :guests_only!def guests_only! redirect_to root_url and return if user_signed_in?end Зачем тут return?
    19. 19. Разгадка• Программист не знает, как работает before_filter.• Он беспокоится, что код контроллера будет выполняться после редиректа в фильтре.• От своего беспокойства он забывает как о том, что нужно возвращать false, так и о том, что после редиректа это уже лишнее.
    20. 20. Более простое объяснение• Код был перенесен в фильтр из экшена.• Программисту просто не хочется его переписывать, потому как кажется, что этот возврат нужен (возвращаемся к исходному объяснению).
    21. 21. Metaprogramming to the recsueif permission.can? can permission.action.to_sym, subjectelse cannot permission.action.to_sym, subjectend vs. method = permission.can? ? :can : :cannot send method, permission.action.to_sym, subject
    22. 22. Способы борьбы• Знание языка• Критический взгляд на свой код• Let it fail (hoptoad в помощь)
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×