Защо rubocop или ruby ​​style guide предпочитат да не използват get_ или set_?

Изпълнявах rubocop по моя проект и коригирах оплакванията, които повдигна.

Едно конкретно оплакване ме притесни

Do not prefix reader method names with get_

Не можах да разбера много от това оплакване, затова погледнах изходния код в github.

Намерих този фрагмент

    def bad_reader_name?(method_name, args)
      method_name.start_with?('get_') && args.to_a.empty?
    end

    def bad_writer_name?(method_name, args)
      method_name.start_with?('set_') && args.to_a.one?
    end

Така че съветът или конвенцията е следният:

1) Всъщност те ни съветват да не използваме get_, когато методът няма аргументи. в противен случай позволяват get_

2) И ни съветват да не използваме set_, когато методът има само един аргумент. В противен случай позволяват set_

Каква е причината зад тази конвенция или правило или съвет?


person Harish Kayarohanam    schedule 29.09.2014    source източник
comment
Заради чистото любопитство, какво е името на метода?   -  person Unixmonkey    schedule 29.09.2014


Отговори (2)


Мисля, че въпросът тук е, че ruby ​​разработчиците предпочитат винаги да мислят за методите като за получаване, тъй като те връщат нещо и използват равното "синтактична захар" (като в def self.dog=(params), което ви позволява да правите Class.dog = something). По същество това, което винаги съм виждал, е, че get и set са излишни и многословни.

В противовес на това имате get и set с множество аргументи, които са като методи за намиране (по-специално get; помислете за where на ActiveRecord).

Имайте предвид, че „ръководство за стил“ = чисто мнение. Последователността е по-високата цел на ръководствата за стил като цяло, така че освен ако нещо не е грешно или трудно за четене, целта ви трябва да бъде по-скоро да имате всичко еднакво, отколкото от определен тип. Ето защо rubocop ви позволява да изключите това.

person Stefan Dorunga    schedule 29.09.2014
comment
Добре . това е убедително. мога ли да накарам ruby ​​cop да пропусне този ред от проверка? - person Harish Kayarohanam; 29.09.2014
comment
Е.. можете да го накарате да пропусне файла или просто да го премахнете напълно в конфигурацията. По този начин той никога няма да се оплаче, но след това няма да ви уведоми, когато използвате get_ в който и да е от файловете. (Кое ви харесва?) Можете да го промените във вашия rubocop конфигурационен файл - person Stefan Dorunga; 02.10.2014
comment
Не искам да го правя за цялото приложение, затова добавих коментара # # rubocop:disable Style/AccessorMethodName # rubocop:enable Style/AccessorMethodName само за този блок. - person Harish Kayarohanam; 06.10.2014

Друг начин да го видите: парадигмата getter/setter беше, доколкото мога да кажа, до голяма степен специфична конвенция в Java/C++ и т.н.; поне познавах доста кодови бази на Java в много мъгливото минало, където Beans бяха осеяни с огромни количества get_-getters и set_-setters. През това време частният атрибут вероятно ще се нарича "name" с "set_name()" и "get_name()"; тъй като самият атрибут се наричаше "име", гетерът не можеше да бъде и "име()".

Следователно самото съществуване на "get_" и "set_" се дължи на (тривиален) технически недостатък на езиците, които не позволяват "=" в имената на методите.

В Ruby имаме доста различен набор от възможности:

  • Първо и най-важно, имаме name() и name=(), което незабавно премахва необходимостта от синтаксиса get_ и set_. И така, ние правим имаме гетери и сетери, просто ги наричаме по различен начин от Java.

  • Освен това атрибутът тогава не е name, а @name, следователно разрешаването на този конфликт също.

  • Всъщност вие изобщо нямате атрибути с обикновен синтаксис "obj.name"! Например; докато Rails/ActiveRecord се преструва, че "person.name" е "атрибут", всъщност е просто двойка автоматично генерирани getter name() и setter name=(). Концептуално, повикващият не трябва да се интересува от това какво е "име" (атрибут или метод), това е детайл от изпълнението на класа.

  • Спестява 4 или 3 натискания на клавиши за всяко повикване. Това може да изглежда като шега, но писането на кратък, но лесно разбираем код е в крайна сметка запазена марка на Ruby. :-)

person AnoE    schedule 14.01.2016
comment
Страхотен отговор! Все още може да има смисъл да има set_ (задаване на глобални състояния) и get_ (get_headers, post_headers, delete_headers (като HTTP глаголи)). Но определено не трябва да се използва като аксесоари в стил Java (напр. attr_accessor може да направи това :D) - person Dorian; 22.04.2017
comment
Добър пример get_headers. Тогава #rubocop:disable ще ви бъде от полза. ;) @Дориан - person AnoE; 22.04.2017