<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                * 使用?`::`?引用常量(包括類和模塊)和構造器 (比如?`Array()`?或者?`Nokogiri::HTML()`)。永遠不要使用?`::`?來調用方法。 ~~~ # 差 SomeClass::some_method some_object::some_method # 好 SomeClass.some_method some_object.some_method SomeModule::SomeClass::SOME_CONST SomeModule::SomeClass() ~~~ * 使用?`def`?時,有參數時使用括號。方法不接受參數時,省略括號。 ~~~ # 差 def some_method() # 此處省略方法體 # 好 def some_method # 此處省略方法體 # 差 def some_method_with_parameters param1, param2 # 此處省略方法體 # 好 def some_method_with_parameters(param1, param2) # 此處省略方法體 end ~~~ * 永遠不要使用?`for`?,除非你很清楚為什么。大部分情況應該使用迭代器。`for`?是由?`each`?實現的。所以你繞彎了,而且?`for`?沒有包含一個新的作用域 (`each`?有 ),因此它區塊中定義的變量將會被外部所看到。 ~~~ arr = [1, 2, 3] # 差 for elem in arr do puts elem end # 注意 elem 會被外部所看到 elem #=> 3 # 好 arr.each { |elem| puts elem } # elem 不會被外部所看到 elem #=> NameError: undefined local variable or method `elem' ~~~ * 永遠不要在多行的?`if/unless`?中使用?`then`。 ~~~ # 差 if some_condition then # 此處省略語句體 end # 好 if some_condition # 此處省略語句體 end ~~~ * 總是在多行的?`if/unless`?中把條件語句放在同一行。 ~~~ # 差 if some_condition do_something do_something_else end # 好 if some_condition do_something do_something_else end ~~~ * 三元操作符?`? :`?比?`if/then/else/end`?結構更為常見也更精準。 ~~~ # 差 result = if some_condition then something else something_else end # 好 result = some_condition ? something : something_else ~~~ * 三元操作符的每個分支只寫一個表達式。即不要嵌套三元操作符。嵌套情況使用?`if/else`?結構。 ~~~ # 差 some_condition ? (nested_condition ? nested_something : nested_something_else) : something_else # 好 if some_condition nested_condition ? nested_something : nested_something_else else something_else end ~~~ * 永遠不要使用?`if x: ...`——它已經在 Ruby 1.9 被移除了。使用三元操作符。 ~~~ # 差 result = if some_condition: something else something_else end # 好 result = some_condition ? something : something_else ~~~ * 永遠不要使用?`if x; ...`?使用三元操作符。 * 利用 if 和 case 是表達式的特性。 ~~~ # 差 if condition result = x else result = y end # 好 result = if condition x else y end ~~~ * 單行情況使用?`when x then ...`。另一種語法?`when x: ...`?已經在 Ruby 1.9 被移除了。 * 永遠不要使用?`when x: ...`。參考前一個規則。 * 使用?`!`?替代?`not`。 ~~~ # 差 - 因為操作符有優先級,需要用括號。 x = (not something) # 好 x = !something ~~~ * 避免使用?`!!`。 ~~~ # 差 x = 'test' # obscure nil check if !!x # body omitted end x = false # double negation is useless on booleans !!x # => false # 好 x = 'test' unless x.nil? # body omitted end ~~~ * `and`?和?`or`?這兩個關鍵字被禁止使用了。 總是使用?`&&`?和?`||`?來取代。 ~~~ # 差 # 布爾表達式 if some_condition and some_other_condition do_something end # 控制流程 document.saved? or document.save! # 好 # 布爾表達式 if some_condition && some_other_condition do_something end # 控制流程 document.saved? || document.save! ~~~ * 避免多行的?`? :`(三元操作符);使用?`if/unless`?來取代。 * 單行主體用?`if/unless`?修飾符。另一個好的方法是使用?`&&/||`?控制流程。 ~~~ # 差 if some_condition do_something end # 好 do_something if some_condition # 另一個好方法 some_condition && do_something ~~~ * 避免在多行區塊后使用?`if`?或?`unless`。 ~~~ # 差 10.times do # multi-line body omitted end if some_condition # 好 if some_condition 10.times do # multi-line body omitted end end ~~~ * 否定判斷時,`unless`(或控制流程的?`||`)優于?`if`(或使用?`||`?控制流程)。 ~~~ # 差 do_something if !some_condition # 差 do_something if not some_condition # 好 do_something unless some_condition # 另一個好方法 some_condition || do_something ~~~ * 永遠不要使用?`unless`?和?`else`?組合。改寫成肯定條件。 ~~~ # 差 unless success? puts 'failure' else puts 'success' end # 好 if success? puts 'success' else puts 'failure' end ~~~ * 不要使用括號圍繞?`if/unless/while`?的條件式。 ~~~ # 差 if (x > 10) # 此處省略語句體 end # 好 if x > 10 # 此處省略語句體 end ~~~ * 在多行?`while/until`?中不要使用?`while/until condition do`?。 ~~~ # 差 while x > 5 do # 此處省略語句體 end until x > 5 do # 此處省略語句體 end # 好 while x > 5 # 此處省略語句體 end until x > 5 # 此處省略語句體 end ~~~ * 單行主體時盡量使用?`while/until`?修飾符。 ~~~ # 差 while some_condition do_something end # 好 do_something while some_condition ~~~ * 否定條件判斷盡量使用?`until`?而不是?`while`?。 ~~~ # 差 do_something while !some_condition # 好 do_something until some_condition ~~~ * 無限循環用?`Kernel#loop`,不用?`while/until`?。 ~~~ # 差 while true do_something end until false do_something end # 好 loop do do_something end ~~~ * 循環后條件判斷使用?`Kernel#loop`?和?`break`,而不是?`begin/end/until`?或者?`begin/end/while`。 ~~~ # 差 begin puts val val += 1 end while val < 0 # 好 loop do puts val val += 1 break unless val < 0 end ~~~ * 忽略圍繞方法參數的括號,如內部 DSL (如:Rake, Rails, RSpec),Ruby 中帶有“關鍵字”狀態的方法(如:`attr_reader`,`puts`)以及屬性存取方法。所有其他的方法呼叫使用括號圍繞參數。 ~~~ class Person attr_reader :name, :age # 忽略 end temperance = Person.new('Temperance', 30) temperance.name puts temperance.age x = Math.sin(y) array.delete(e) bowling.score.should == 0 ~~~ * 省略可選哈希參數的外部花括號。 ~~~ # 差 user.set({ name: 'John', age: 45, permissions: { read: true } }) # 好 User.set(name: 'John', age: 45, permissions: { read: true }) ~~~ * 如果方法是內部 DSL 的一部分,那么省略外層的花括號和圓括號。 ~~~ class Person < ActiveRecord::Base # 差 validates(:name, { presence: true, length: { within: 1..10 } }) # 好 validates :name, presence: true, length: { within: 1..10 } end ~~~ * 如果方法調用不需要參數,那么省略圓括號。 ~~~ # 差 Kernel.exit!() 2.even?() fork() 'test'.upcase() # 好 Kernel.exit! 2.even? fork 'test'.upcase ~~~ * 當被調用的方法是只有一個操作的區塊時,使用`Proc`。 ~~~ # 差 names.map { |name| name.upcase } # 好 names.map(&:upcase) ~~~ * 單行區塊傾向使用?`{...}`?而不是?`do...end`。多行區塊避免使用?`{...}`(多行串連總是??丑陋)。在?`do...end`?、 “控制流程”及“方法定義”,永遠使用?`do...end`?(如 Rakefile 及某些 DSL)。串連時避免使用?`do...end`。 ~~~ names = %w(Bozhidar Steve Sarah) # 差 names.each do |name| puts name end # 好 names.each { |name| puts name } # 差 names.select do |name| name.start_with?('S') end.map { |name| name.upcase } # 好 names.select { |name| name.start_with?('S') }.map(&:upcase) ~~~ 某些人會爭論多行串連時,使用?`{...}`?看起來還可以,但他們應該捫心自問——這樣代碼真的可讀嗎?難道不能把區塊內容取出來放到小巧的方法里嗎? * 顯性使用區塊參數而不是用創建區塊字面量的方式傳遞參數給區塊。此規則對性能有所影響,因為區塊先被轉化為`Proc`。 ~~~ require 'tempfile' # 差 def with_tmp_dir Dir.mktmpdir do |tmp_dir| Dir.chdir(tmp_dir) { |dir| yield dir } # block just passes arguments end end # 好 def with_tmp_dir(&block) Dir.mktmpdir do |tmp_dir| Dir.chdir(tmp_dir, &block) end end with_tmp_dir do |dir| # 使用上面的方法 puts "dir is accessible as a parameter and pwd is set: #{dir}" end ~~~ * 避免在不需要控制流程的場合時使用?`return`?。 ~~~ # 差 def some_method(some_arr) return some_arr.size end # 好 def some_method(some_arr) some_arr.size end ~~~ * 避免在不需要的情況使用?`self`?。(只有在調用一個 self write 訪問器時會需要用到。) ~~~ # 差 def ready? if self.last_reviewed_at > self.last_updated_at self.worker.update(self.content, self.options) self.status = :in_progress end self.status == :verified end # 好 def ready? if last_reviewed_at > last_updated_at worker.update(content, options) self.status = :in_progress end status == :verified end ~~~ * 避免局部變量 shadowing 外部方法,除非它們彼此相等。 ~~~ class Foo attr_accessor :options # 勉強可以 def initialize(options) self.options = options # 此處 options 和 self.options 都是等價的 end # 差 def do_something(options = {}) unless options[:when] == :later output(self.options[:message]) end end # 好 def do_something(params = {}) unless params[:when] == :later output(options[:message]) end end end ~~~ * 不要在條件表達式里使用?`=`?(賦值)的返回值,除非條件表達式在圓括號內被賦值。這是一個相當流行的 Ruby 方言,有時被稱為“safe assignment in condition”。 ~~~ # 差 (還會有個警告) if (v = array.grep(/foo/)) do_something(v) ... end # 差 (MRI 仍會抱怨, 但 RuboCop 不會) if v = array.grep(/foo/) do_something(v) ... end # 好 v = array.grep(/foo/) if v do_something(v) ... end ~~~ * 變量自賦值用簡寫方式。 ~~~ # 差 x = x + y x = x * y x = x**y x = x / y x = x || y x = x && y # 好 x += y x *= y x **= y x /= y x ||= y x &&= y ~~~ * 如果變量未被初始化過,用?`||=`?來初始化變量并賦值。 ~~~ # 差 name = name ? name : 'Bozhidar' # 差 name = 'Bozhidar' unless name # 好 僅在 name 為 nil 或 false 時,把名字設為 Bozhidar。 name ||= 'Bozhidar' ~~~ * 不要使用?`||=`?來初始化布爾變量。 (想看看如果現在的值剛好是?`false`?時會發生什么。) ~~~ # 差——會把 `enabled` 設成真,即便它本來是假。 enabled ||= true # 好 enabled = true if enabled.nil? ~~~ * 使用 &&= 可先檢查是否存在變量,如果存在則做相應動作。這樣就無需用?`if`?檢查變量是否存在了。 ~~~ # 差 if something something = something.downcase end # 差 something = something ? something.downcase : nil # 可以 something = something.downcase if something # 好 something = something && something.downcase # 更好 something &&= something.downcase ~~~ * 避免使用?`case`?語句的?`===`?操作符(case equality operator)。從名稱可知,這是?`case`?臺面下所用的操作符,在`case`?語句外的場合使用,會產生難以理解的代碼。 ~~~ # 差 Array === something (1..100) === 7 /something/ === some_string # 好 something.is_a?(Array) (1..100).include?(7) some_string =~ /something/ ~~~ * 避免使用 Perl 風格的特殊變量(像是?`$:`、`$;`?等)。它們看起來非常神秘,除非用于單行腳本,否則不鼓勵使用。使用?`English`?庫提供的友好別名。 ~~~ # 差 $:.unshift File.dirname(__FILE__) # 好 require 'English' $LOAD_PATH.unshift File.dirname(__FILE__) ~~~ * 永遠不要在方法名與左括號之間放一個空格。 ~~~ # 差 f (3 + 2) + 1 # 好 f(3 + 2) + 1 ~~~ * 如果方法的第一個參數由左括號開始的,則此方法調用應該使用括號。舉個例子,如?`f((3+2) + 1)`。 * 總是使用?`-w`?來執行 Ruby 解釋器,如果你忘了某個上述的規則,它就會警告你! * 用新的 lambda 字面語法定義單行區塊,用?`lambda`?方法定義多行區塊。 ~~~ # 差 lambda = lambda { |a, b| a + b } lambda.call(1, 2) # 正確,但看著怪怪的 l = ->(a, b) do tmp = a * 7 tmp * b / 50 end # 好 l = ->(a, b) { a + b } l.call(1, 2) l = lambda do |a, b| tmp = a * 7 tmp * b / 50 end ~~~ * 當定義一個簡短且沒有參數的 lambda 時,省略參數的括號。 ~~~ # 差 l = ->() { something } # 好 l = -> { something } ~~~ * 用?`proc`?而不是?`Proc.new`。 ~~~ # 差 p = Proc.new { |n| puts n } # 好 p = proc { |n| puts n } ~~~ * 用?`proc.call()`?而不是?`proc[]`?或?`proc.()`。 ~~~ # 差 - 看上去像枚舉訪問 l = ->(v) { puts v } l[1] # 也不好 - 不常用的語法 l = ->(v) { puts v } l.(1) # 好 l = ->(v) { puts v } l.call(1) ~~~ * 未使用的區塊參數和局部變量使用?`_`?前綴或直接使用?`_`(雖然表意性差些) 。Ruby解釋器和RuboCop都能辨認此規則,并會抑制相關地有變量未使用的警告。 ~~~ # 差 result = hash.map { |k, v| v + 1 } def something(x) unused_var, used_var = something_else(x) # ... end # 好 result = hash.map { |_k, v| v + 1 } def something(x) _unused_var, used_var = something_else(x) # ... end # 好 result = hash.map { |_, v| v + 1 } def something(x) _, used_var = something_else(x) # ... end ~~~ * 使用?`$stdout/$stderr/$stdin`?而不是?`STDOUT/STDERR/STDIN`。`STDOUT/STDERR/STDIN`?是常量,雖然在 Ruby 中是可以給常量重新賦值的(可能是重定向到某個流),但解釋器會警告。 * 使用?`warn`?而不是?`$stderr.puts`。除了更加清晰簡潔,如果你需要的話,?`warn`?還允許你壓制(suppress)警告(通過?`-W0`?將警告級別設為?`0`)。 * 傾向使用?`sprintf`?和它的別名?`format`?而不是相當隱晦的?`String#%`?方法. ~~~ # 差 '%d %d' % [20, 10] # => '20 10' # 好 sprintf('%d %d', 20, 10) # => '20 10' # 好 sprintf('%{first} %{second}', first: 20, second: 10) # => '20 10' format('%d %d', 20, 10) # => '20 10' # 好 format('%{first} %{second}', first: 20, second: 10) # => '20 10' ~~~ * 傾向使用?`Array#join`?而不是相當隱晦的使用字符串作參數的?`Array#*`。 ~~~ # 差 %w(one two three) * ', ' # => 'one, two, three' # 好 %w(one two three).join(', ') # => 'one, two, three' ~~~ * 當處理你希望將變量作為數組使用,但不確定它是不是數組時, 使用?`[*var]`?或?`Array()`?而不是顯式的?`Array`?檢查。 ~~~ # 差 paths = [paths] unless paths.is_a? Array paths.each { |path| do_something(path) } # 好 [*paths].each { |path| do_something(path) } # 好(而且更具易讀性一點) Array(paths).each { |path| do_something(path) } ~~~ * 盡量使用范圍或?`Comparable#between?`?來替換復雜的邏輯比較。 ~~~ # 差 do_something if x >= 1000 && x < 2000 # 好 do_something if (1000...2000).include?(x) # 好 do_something if x.between?(1000, 2000) ~~~ * 盡量用判斷方法而不是使用?`==`?。比較數字除外。 ~~~ # 差 if x % 2 == 0 end if x % 2 == 1 end if x == nil end # 好 if x.even? end if x.odd? end if x.nil? end if x.zero? end if x == 0 end ~~~ * 除非是布爾值,不用顯示檢查它是否不是?`nil`?。 ~~~ # 差 do_something if !something.nil? do_something if something != nil # 好 do_something if something # 好——檢查的是布爾值 def value_set? !@some_boolean.nil? end ~~~ * 避免使用?`BEGIN`?區塊。 * 使用?`Kernel#at_exit`?。永遠不要用?`END`?區塊。 ~~~ # 差 END { puts 'Goodbye!' } # 好 at_exit { puts 'Goodbye!' } ~~~ * 避免使用 flip-flops 。 * 避免使用嵌套的條件來控制流程。 當你可能斷言不合法的數據,使用一個防御從句。一個防御從句是一個在函數頂部的條件聲明,這樣如果數據不合法就能盡快的跳出函數。 ~~~ # 差 def compute_thing(thing) if thing[:foo] update_with_bar(thing) if thing[:foo][:bar] partial_compute(thing) else re_compute(thing) end end end # 好 def compute_thing(thing) return unless thing[:foo] update_with_bar(thing[:foo]) return re_compute(thing) unless thing[:foo][:bar] partial_compute(thing) end ~~~ 使用?`next`?而不是條件區塊。 ~~~ # 差 [0, 1, 2, 3].each do |item| if item > 1 puts item end end # 好 [0, 1, 2, 3].each do |item| next unless item > 1 puts item end ~~~ * 傾向使用?`map`?而不是?`collect`?,?`find`?而不是?`detect`?,?`select`?而不是?`find_all`?,?`reduce`?而不是?`inject`以及?`size`?而不是?`length`?。這不是一個硬性要求;如果使用別名增加了可讀性,使用它沒關系。這些有押韻的方法名是從 Smalltalk 繼承而來,在別的語言不通用。鼓勵使用?`select`?而不是?`find_all`?的理由是它跟?`reject`?搭配起來是一目了然的。 * 不要用?`count`?代替?`size`。除了`Array`其它`Enumerable`對象都需要遍歷整個集合才能得到大小。 ~~~ # 差 some_hash.count # 好 some_hash.size ~~~ * 傾向使用?`flat_map`?而不是?`map`?+?`flatten`?的組合。 這并不適用于深度大于 2 的數組,舉個例子,如果`users.first.songs == ['a', ['b', 'c']]`?,則使用?`map + flatten`?的組合,而不是使用?`flat_map`。?`flat_map`將數組變平坦一個層級,而?`flatten`?會將整個數組變平坦。 ~~~ # 差 all_songs = users.map(&:songs).flatten.uniq # 好 all_songs = users.flat_map(&:songs).uniq ~~~ * 使用?`reverse_each`?,不用?`reverse.each`?。?`reverse_each`?不會重新分配新數組。 ~~~ # 差 array.reverse.each { ... } # 好 array.reverse_each { ... } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看