Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Беспокойный код    @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

754 views

Published on

Published in: Education
  • Be the first to like this

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 в помощь)

×