
目錄

Reek是一種研究Ruby類,模塊和方法的工具,並報告了發現的任何代碼氣味。
為了很好地介紹代碼氣味,請查看此博客文章或該文章。 RubyConfby也有此談話(如果您喜歡的話,還有一個幻燈片)。
通過RubyGems安裝它:
gem install reek並這樣運行:
reek [options] [dir_or_source_file] * 想像一個源文件demo.rb包含:
# Smelly class
class Smelly
# This will reek of UncommunicativeMethodName
def x
y = 10 # This will reek of UncommunicativeVariableName
end
endREEK將報告此文件中以下代碼聞到:
$ reek --no-documentation demo.rb
Inspecting 1 file(s):
S
demo.rb -- 2 warnings:
[4]:UncommunicativeMethodName: Smelly#x has the name 'x'
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
Reek正式支持Crouby 3.0至3.3和Jruby 9.4。其他紅寶石實施(例如Rubinius)不得到正式支持,但也應該工作。
請注意,在每個Ruby版本上,Reek將使用解析器作為Ruby。因此,您應該始終使用項目的目標紅寶石版本之一運行Reek。
Reek專注於高級代碼的氣味,因此我們無法告訴您如何以通用方式修復警告;這是並且將始終完全取決於您的領域語言和業務邏輯。
也就是說,一個例子可能會幫助您開始。看看Ruby在Rails模型上的樣本(請注意,這是被截斷的,而不是工作代碼):
class ShoppingCart < ActiveRecord :: Base
has_many :items
def gross_price
items . sum { | item | item . net + item . tax }
end
end
class Item < ActiveRecord :: Base
belongs_to :shopping_cart
end這樣的文件上運行reek:
reek app/models/shopping_cart.rb
將報告:
[5, 5]:ShoppingCart#gross_price refers to item more than self (FeatureEnvy)
解決此問題非常簡單。將其屬於單一項目的總價計算,這將是Item類:
class ShoppingCart < ActiveRecord :: Base
has_many :items
def gross_price
items . sum { | item | item . gross_price }
end
end
class Item < ActiveRecord :: Base
belongs_to :shopping_cart
def gross_price
net + tax
end
end代碼聞到的文檔可能會給您進一步的提示 - 當您有警告時,請務必先檢查一下這些內容。
您可以通過多種方式在來源上工作,最常見的方法只是
reek lib/如果您沒有通過任何源參數來撤銷,則只需將當前的工作目錄作為源。
所以
reek與明確的完全相同:
reek .此外,您可以將代碼管傳送到這樣:
echo " class C; def m; end; end " | reek這將打印出來:
$stdin -- 3 warnings:
[1]:C has no descriptive comment (IrresponsibleModule)
[1]:C has the name ' C ' (UncommunicativeModuleName)
[1]:C#m has the name ' m ' (UncommunicativeMethodName)Reek當前包括檢查控制夫婦的某些方面,數據集團,特徵嫉妒,大型班級,長參數列表,模擬多態性,過多的語句,不傳奇的名稱,未使用的參數等等。請參閱代碼氣味,以獲取最新的詳細信息REEK將在您的代碼中檢查哪些內容。
有爭議的探測器的特殊配置:
默認情況下未使用的私人方法被禁用,因為它是有爭議的,這意味著您必須通過配置中的配置明確激活它
UnusedPrivateMethod :
enabled : true公用事業功能也是一個有爭議的探測器,可能確實是不受歡迎的。結果,我們可以將其禁用以這樣的非公共方法:
---
UtilityFunction :
public_methods_only : true 對於基本概述,運行
reek -- help有關這些CLI選項的摘要,請參閱命令行選項。
通過配置文件配置Reek是迄今為止最強大的方法。 Reek希望該文件名是.reek.yml ,但您可以通過CLI -c開關覆蓋此名稱(請參見下文)。
通過三種方法,可以將Reek傳遞給配置文件:
-c開關(請參閱上面的命令行接口)Reek試圖找到此類配置文件的順序正是上述:首先,它通過CLI明確地檢查了它是否給了配置文件;然後,它檢查了當前的工作目錄中是否有一個文件,如果找不到一個文件,它會遍歷目錄,直到登錄根目錄。最後,它檢查您的主目錄。
Reek一旦檢測到配置文件就會立即停止搜索,這意味著從Reek的角度來看,就完全存在一個配置文件和一種配置,無論您在文件系統上可能有多少個*.reek文件。
我們付出了很多努力,使Reek的配置盡可能地自我解釋,因此了解它的最佳方法是通過查看一個簡單的示例(例如,您的項目目錄中的.reek.yml ):
---
# ## Generic smell configuration
detectors :
# You can disable smells completely
IrresponsibleModule :
enabled : false
# You can use filters to silence Reek warnings.
# Either because you simply disagree with Reek (we are not the police) or
# because you want to fix this at a later point in time.
NestedIterators :
exclude :
- " MyWorker#self.class_method " # should be refactored
- " AnotherWorker#instance_method " # should be refactored as well
# A lot of smells allow fine tuning their configuration. You can look up all available options
# in the corresponding smell documentation in /docs. In most cases you probably can just go
# with the defaults as documented in defaults.reek.yml.
DataClump :
max_copies : 3
min_clump_size : 3
# ## Directory specific configuration
# You can configure smells on a per-directory base.
# E.g. the classic Rails case: controllers smell of NestedIterators (see /docs/Nested-Iterators.md) and
# helpers smell of UtilityFunction (see docs/Utility-Function.md)
#
# Note that we only allow configuration on a directory level, not a file level,
# so all paths have to point to directories.
# A Dir.glob pattern can be used.
directories :
" web_app/app/controllers " :
NestedIterators :
enabled : false
" web_app/app/helpers** " :
UtilityFunction :
enabled : false
" web_app/lib/**/test/** " :
UtilityFunction :
enabled : false
# ## Excluding directories
# Directories and files below will not be scanned at all
exclude_paths :
- lib/legacy
- lib/rake/legacy_tasks
- lib/smelly.rb如上所述,Reek的配置包括3個不同的部分,由3個不同的鍵表示:
無論您在配置中添加的任何內容都應在其中一個密鑰下範圍範圍。
如果您有一個目錄指令,默認指令的目錄指令(目錄指令)將優先。
例如,此配置:
---
detectors :
IrresponsibleModule :
enabled : false
TooManyStatements :
max_statements : 5
directories :
" app/controllers " :
TooManyStatements :
max_statements : 10轉換為:
每個氣味探測器都支持我們的基本氣味選擇。如上所述,某些氣味類型提供的配置超出了基本氣味選項的配置,例如數據集團。超出基本氣味選項的所有選項都記錄在“相應氣味類型 /文檔”頁面中(如果您想對所有可能的配置進行快速概述,也可以在此存儲庫中查看defaults.reek.yml文件。
請注意,您根本不需要配置文件。如果您對所有默認設置都很好,則可以完全跳過。
不用擔心在配置文件中引入一個錯誤可能不會引起注意的錯誤 - Reek使用模式來驗證您的配置在啟動時對您的配置進行驗證,並且如果您拼寫錯誤或使用錯誤的數據類型,則會大聲失敗。
Error: We found some problems with your configuration file: [/detectors/DetectorWithTypo] key 'DetectorWithTypo:' is undefined.
Reek僅使用一個配置文件和一個配置文件,而.reek.yml為默認名稱。
如果您必須在目錄中有一個或多個配置文件(例如,您要使用不同的,相互排斥的設置在玩耍),則需要明確告訴Reek哪個文件可以通過reek -c config.reek使用。
如果您需要抑制氣味警告,並且由於某種原因,您也不能或不想使用配置文件,您也可以使用類似的特殊源代碼註釋:
# This method smells of :reek:NestedIterators
def smelly_method foo
foo . each { | bar | bar . each { | baz | baz . qux } }
end您甚至可以傳遞特定的配置設置:
# :reek:NestedIterators { max_allowed_nesting: 2 }
def smelly_method foo
foo . each { | bar | bar . each { | baz | baz . qux } }
end這是一個非常強大的功能,並在氣味抑制下進一步解釋。
使用Reeks的動態機制,可以找到一個配置文件,您可能會遇到您無法100%確定使用什麼配置文件REEK使用的情況。例如,您的項目根中有一個特定項目的配置文件,還有您用於所有其他項目的主目錄中的另一種REEK配置,無論出於何種原因,Reek似乎都使用了其他配置文件,而不是您假設的文件。
在這種情況下,您可以將標誌--show-configuration-path傳遞給Reek,這將使Reek輸出其使用的配置文件的路徑。
將Reek等工具集成到現有的較大代碼庫中可能會令人生畏,而您必須首先修復數百或數千個氣味警告。當然,您可以手動禁用如上圖所示的氣味警告,但根據代碼庫的大小,這可能不是一個選擇。幸運的是,Reek提供了一個“ todo”標誌,您可以用來生成一種配置,該配置將抑制當前代碼庫的所有氣味警告:
reek --todo lib/這將在您當前的工作目錄中創建文件'.reek.yml'。
然後,您可以將其用作您的配置 - 由於您的工作目錄可能是您的項目根,因此在大多數情況下,您不必明確地告訴Reek使用'.reek.yml',因為Reek會自動將其拾取並將其用作配置文件。請參閱上面的配置加載。
如果出於任何原因,您決定將“ .reek.yml”放置在其他地方,那麼Reek不會自動撿起它,則需要明確告訴Reek才能通過:
reek -c whatever/.reek.yml lib/重要的是要了解--todo標誌的第一用例應在引入Reek的開頭時一次運行以簡化過渡。如果您發現自己想用--todo Flag重新運行Reek,以使許多新警告保持沉默,那麼您將擊敗--todo國旗和Reek本身的目的。
結果,再次使用--todo標誌運行Reek不會覆蓋現有的“ .reek.yml”,而不是中止執行。它也不會考慮您可能考慮的任何其他配置文件。
這意味著當您運行時
reek -c other_configuration.reek --todo lib/ other_configuration.reek將被簡單地忽略。
當然,您始終可以刪除現有的.reek.yml文件,然後使用--todo標誌運行Reek,但請記住,這不是此功能的預期用例。
除了顯而易見
reek [options] [dir_or_source_file] *在項目中使用Reek還有很多其他方法:
查看源代碼後要做的第一件事是運行Bundler:
bundle install
然後運行測試:
bundle exec rspec spec/your/file_spec.rb # Runs all tests in spec/your/file_spec.rb
bundle exec rspec spec/your/file_spec.rb:23 # Runs test in line 23
bundle exec cucumber features/your_file.feature # Runs all scenarios in your_file.feature
bundle exec cucumber features/your_file.feature:23 # Runs scenario at line 23或者只是運行整個測試套件:
bundle exec rake
這將運行測試(RSPEC和Cucumber),Rubocop和Reek本身。
另一個有用的耙子任務是console任務。這將使您直接進入一個可以使用Reeks模塊和課程來玩耍的環境:
bundle exec rake console
irb(main):001> Reek::Examiner
=> Reek::Examiner
您還可以在要開始調試的點上添加以下內容來使用IRB時使用IRB:
binding . irb看看我們的開發人員API以獲取更多靈感。
從那時起,您應該退房:
如果您不想用代碼弄髒雙手,您還有其他方法可以幫助我們:
如果您遇到代碼氣候問題(例如,瀏覽代碼重複閾值),您可能希望能夠在本地使用REEK代碼庫來運行代碼氣候。為此,您需要執行以下操作:
gem install codeclimatecodeclimate engines:install現在,您可以運行各種代碼氣候引擎,例如, codeclimate analyze -e duplication
REEK支持6種輸出格式:
--format html )--format yaml ,另請參見YAML報告)--format json )--format xml )--format github ) 使reek“ rails” - 友好型非常簡單,因為我們支持目錄特定的配置(Reek Talk中的directory directives )。只需將其添加到您的配置文件中:
directories :
" app/controllers " :
IrresponsibleModule :
enabled : false
NestedIterators :
max_allowed_nesting : 2
UnusedPrivateMethod :
enabled : false
InstanceVariableAssumption :
enabled : false
" app/helpers " :
IrresponsibleModule :
enabled : false
UtilityFunction :
enabled : false
" app/mailers " :
InstanceVariableAssumption :
enabled : false
" app/models " :
InstanceVariableAssumption :
enabled : false不過,請注意,Reek不要合併您的配置條目,因此,如果您已經有針對“應用程序/控制器”或“應用程序/幫助者”的目錄指令,則需要更新這些指令,而不是將上述YAML示例複製到配置文件中。
您可能想研究的其他靜態代碼分析儀的非排量列表:
REEK核心團隊由:
Reek的原始作者是Kevin Rutherford。
Reek徽標的作者是Sonja Heinen。
值得注意的貢獻來自: