
جدول المحتويات

REEK هي أداة تفحص فصول Ruby والوحدات النمطية والأساليب وتقارير أي رمز تنبعث منه رائحة.
للحصول على مقدمة ممتازة لرائحة الرمز و REEK تحقق من منشور المدونة هذا أو تلك. هناك أيضًا هذا الحديث من 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
endسيقوم Reek بالإبلاغ عن رائحة الرمز التالي في هذا الملف:
$ 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 رسميًا لـ Cruby من 3.0 إلى 3.3 ولجيروبي 9.4. لا يتم دعم تطبيقات Ruby الأخرى (مثل Rubinius) رسميًا ولكن يجب أن تعمل أيضًا.
لاحظ أنه في كل إصدار من Ruby ، ستستخدم Reek المحلل لهذا الإصدار من Ruby. لذلك ، يجب عليك دائمًا تشغيل Reek باستخدام أحد إصدارات Ruby المستهدفة لمشروعك.
تركز Reek على رائحة الكود عالية المستوى ، لذلك لا يمكننا إخبارك بكيفية إصلاح التحذيرات بطريقة عامة ؛ هذا وسيعتمد دائمًا على لغة المجال ومنطق العمل الخاص بك.
ومع ذلك ، قد يساعدك مثال على الذهاب. ألق نظرة على هذه العينة من نموذج Ruby on 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 .بالإضافة إلى ذلك ، يمكنك أن تعيد الرمز إلى 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 (انظر أدناه).
هناك ثلاث طرق لتمرير ملف التكوين:
-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 علامة "TODO" يمكنك استخدامه لإنشاء تكوين من شأنه أن يقمع جميع تحذيرات الرائحة في قاعدة الشفرة الحالية:
reek --todo lib/سيؤدي ذلك إلى إنشاء ملف '.reek.yml' في دليل العمل الحالي الخاص بك.
يمكنك بعد ذلك استخدام هذا التكوين الخاص بك - نظرًا لأن دليل العمل الخاص بك هو جذر المشروع في معظم الحالات ، فلا يتعين عليك إخبار Reek بشكل صريح لاستخدامه. انظر تحميل التكوين أعلاه.
إذا قررت لأي سبب من الأسباب أن تضعها '.reek.yml' في مكان آخر حيث لن يستقلها Reek تلقائيًا ، فأنت بحاجة إلى إخبار Reek بشكل صريح للقيام بذلك عن طريق:
reek -c whatever/.reek.yml lib/ من المهم أن نفهم أن حالة الاستخدام رقم واحد من العلم --todo يجب تشغيله مرة واحدة في بداية إدخال Reek لتخفيف الانتقال. إذا وجدت نفسك ترغب في إعادة تشغيل العلم- --todo من أجل إسكات الكثير من التحذيرات الجديدة التي تهزمها الغرض من العلم- --todo و REEK نفسه.
نتيجة لذلك ، فإن تشغيل Reek مع علامة --todo مرة أخرى لن يكتب فوق ".rek.yml" وبدلاً من ذلك في الإحباط. كما أنه لن يأخذ أي ملف تكوين آخر قد يكون لديك في الاعتبار.
هذا يعني أنه عند الركض
reek -c other_configuration.reek --todo lib/ سيتم تجاهل other_configuration.reek ببساطة.
بالطبع ، يمكنك دائمًا حذف ملف .rek.yml الموجود ثم قم بتشغيله مع العلم --todo ولكن ضع في اعتبارك أن هذه ليست حالة الاستخدام المقصود لهذه الميزة.
إلى جانب ما هو واضح
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 أثناء إجراء الاختبارات عن طريق إضافة ما يلي في النقطة التي تريد بدء تصحيح الأخطاء:
binding . irbإلقاء نظرة على API المطور لدينا لمزيد من الإلهام.
من ذلك الحين يجب عليك التحقق من:
إذا كنت لا تشعر بأنك تتسخ يديك مع الكود ، فلا تزال هناك طرق أخرى يمكنك مساعدتنا فيها:
إذا واجهت مشكلات Code Code Commine (على سبيل المثال ، تجاوز عتبة تكرار الكود) ، فقد ترغب في تشغيل مناخ الرمز مقابل قاعدة Codebase 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"-Friendly بسيطًا إلى حد ما نظرًا لأننا ندعم تكوينات محددة للدليل ( directory directives في Reek Talk). فقط أضف هذا إلى ملف التكوين الخاص بك:
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 بدمج إدخالات التكوين الخاصة بك ، لذلك إذا كان لديك بالفعل توجيه الدليل لـ "APP/Controllers" أو "App/Appers" ، فأنت بحاجة إلى تحديث تلك التوجيهات بدلاً من نسخ عينة Yaml أعلاه إلى ملف التكوين الخاص بك.
قائمة غير شاملة لمحللي الرموز الثابتة الأخرى التي قد ترغب في النظر إليها:
يتكون فريق Reek Core من:
المؤلف الأصلي لـ Reek هو كيفن راذرفورد.
مؤلف شعار Reek هو Sonja Heinen.
جاءت المساهمات الملحوظة من: