Навмисні помилки, щоб уникнути зарезервованих слів


45

Я часто бачу код, який включає навмисні написання загальних слів, які на краще чи гірше стали зарезервованими словами:

  • klassабо clazzдля класу :Class clazz = ThisClass.class
  • kountдля підрахунку в SQL:count(*) AS kount

Особисто я вважаю, що це зменшує читабельність. У власній практиці я не знайшов занадто багато випадків, коли кращого імені не можна було використовувати - itemClassабо recordTotal.

Приклад з JavaDocs for Class показує це в параметрах:

 public <U> Class<? extends U> asSubclass(Class<U> clazz)

Чи показує це розумний випадок використання?


9
Для запису: У Python cls- це загальне (насправді, одне ідіоматичне) ім'я змінних / аргументів, що містять фактичні класи (ті, які ви декларуєте за допомогою classключового слова і для яких все є екземпляром).

14
Вам не подобається typedef char ínt?
Джефф

14
@muntoo Ви маєте рацію. Я також отримую помилки компілятора для iñt. Там іде мій план світового домінування.
Джефф

1
Я порушив це правило ... і тепер відчуваю сором.
jmq

3
Не робіть цього. Я можу чесно сказати, що раніше цього ніколи не бачив, і якби це зробив, то негайно перейменував би це. Просто скорочуйте, якщо вам потрібно використовувати не описову назву змінної ( Class c).
Коді Грей

Відповіді:


63

ІМХО, це дуже погана ідея. Зарезервовані слова зарезервовані з причини, і це робить зменшення читабельності.

Я також повністю згоден з вашим другим моментом. Іменування змінної class, навіть якщо ви могли це зробити, було б так само погано, як іменування її tmpабо a. Який клас? Клас чого? Назви повинні бути описовими.


15
"Зарезервовані слова зарезервовані з причини" <- Це. (Що, як не дивно, зарезервовано.)
пробірка

16
+1, тому що ти маєш рацію. Але якщо ви писали програмне забезпечення для планування в класі, чи щось, клас може бути законною змінною або назвою класу ...
CaffGeek

8
Мех. " Зарезервовані слова зарезервовані з причини ", а це те, що мовні дизайнери ліниві. Існує досить багато складних мов, де слова зарезервовані лише в певних місцях, де вони використовуються. Але Річі почав цю тенденцію, коли йому потрібен був легкий компілятор для C, і більшість мовних дизайнерів дізналися його звідти.
Росс Паттерсон

14
ні Росс, це тому, що програмісти (і читачі взагалі) очікують, що речі мають досить однозначне значення (саме тому, вивчення іноземних мов часто таке важке, всі речі з подвійним значенням або значення, що відрізняються від мови, на якій ви були виховані з дитинства, де ви ніколи не помічаєте цих неоднозначностей, оскільки вони є частиною вашої культурної спадщини).
1313

3
@AlexanderMorou Nope, і не мають більшості мовних дизайнерів, вони просто починають з чужого дизайну. Але подивіться на Algol, Fortran, PL / I, Rexx та інші мови, які не базуються на C, і ви побачите, що граматики без зарезервованих слів, безумовно, можливі, просто складніше. Рітчі мав вагомі причини - люди з Unix відчували, що кожен натискання клавіш має значення, а на PDP-11 кожен цикл процесора мав значення. Сьогодні? Не так багато.
Росс Паттерсон

21

Даний посібник із стилів Python конкретно вирішує цю проблему та пропонує:

Якщо ім’я вашого загальнодоступного атрибута стикається із зарезервованим ключовим словом, додайте до імені атрибута єдиний кінцевий підкреслення. Це краще, ніж абревіатура або зіпсований правопис.

Це здається досить хорошим загальним правилом, якщо припустити, що воно не суперечить семантиці певної мови.


7
Я вважаю, що це справді погана порада у стильовому посібнику. Якщо ім’я вашого атрибута настільки близьке до ключового слова, вам слід знайти краще ім’я. Просто накреслення підкреслення в кінці не додає жодного значення, і, можливо, буде заплутати наступного хлопця, який читає код.
Уейн Джонстон

18
@Wayne: Як ви будете називати операцію об'єднання в структурі пошуку об'єднання, коли unionце ключове слово (як у С)? Ви збираєтесь називати це fooлише тому, що він не повинен виглядати union?
Фред Фоо

OTOH, clsстандартна назва аргументу для методу класу. Також, наприклад, у Django об'єкти мають .idатрибут, що, звичайно, суперечить idвбудованій функції.
vartec

1
@GoloRoden Я ніколи не чув, щоб хтось говорив, що вони "об'єднували" два набори при обчисленні союзу. Це просто не є частиною лінгва. "Злиття" було б краще, але для mergeметоду все одно потрібна документація, в якій чітко зазначено, що він реалізує об'єднання і перейменований з чисто технічних причин.
Фред Фо

2
@GoloRoden За словами Merriam-Webster, це не дієслово, але дивіться цю відповідь .
maaartinus

18

Кодовий запах.

string stringVariable = "";

Наведений вище код нічого не каже мені про змінні, які планується використовувати.

class Klass

Та ж проблема

string UserNameString = "bmackey"

Наведений вище код не повинен вимагати рядка ключового слова, доданого до імені змінної. Якщо вам потрібно визначити типи за назвою змінної, ваш код занадто довгий. Конденсатор-рефактор.


Це нічого не говорить вам, оскільки це не "код", це окреме оголошення змінної. "Клас" або "клас", можливо, дуже добре розкажуть вам все, що вам потрібно знати. Наприклад, загальний метод може отримати Class<T>параметр, і це може мати сенс. Тож я не згоден, що це кодовий запах.
Андрес Ф.

5

Особисто я вважаю, що це абсолютно вірний варіант для вашого стилю коду.

Вони зарезервовані слова, тому компілятору не доведеться вирішувати, чи ви мали на увазі мову-механіку чи вашу змінну. Зважаючи на це, це означає, що вони очікують, що люди матимуть потребу в змінній, як зарезервоване слово.

Перебираючи джерело в комплекті з JDK 1.6 R21, я знаходжу 917 випадків "клазу". Мабуть, вони вважали це прийнятним стилем.

Як ваша команда ставиться до цього? Якщо ви вважаєте, що це погано, але інші 9 хлопців з вашої команди вважають, що це добре, то вам доведеться кусати кулю і прийняти її. Поки є повідомлення про те, що добре, а що ні, і ви ставите проблеми, які ви бачите так, як їх бачите, це повинно бути добре.

Те, як ваша команда ставиться до стилю коду, важливіше, ніж моя думка, чи хтось інший у цій публікації . Це стосується цього та будь-яких інших рішень у стилі коду, які ви можете мати.


1
Правильно, але з часом ваша команда зміниться. Через багато років по дорозі з’явиться якийсь бідний хлопець, який дивиться на ваш код, повний класів та кладзів, і каже "WTF!".
MrFox

4
Якщо ви використовуєте klassі clazzте, і інше , це погано. Потрібно бути послідовним, тому їм доведеться навчитися цьому лише один раз. І в ідеалі це також прописано в настановах стилів для команд, тож це не є великим сюрпризом.
corsiKa

Код написаний не просто для людей у ​​вашій команді, а для того, щоб прочитати інший світ. Коли ваша команда перебуває в автобусі, який їде через скелю, хтось ще повинен почати читати код. Використовуйте імена, які повністю і стисло описують, що таке змінна, а не як вона представлена.
Роб К

1
Ні, просто ні. Ваша команда далеко, набагато більше шансів повільно обертати членів. Ви можете планувати, щоб одна людина потрапила в автобус, але ви не можете планувати, щоб ваша команда потрапила в автобус. Більшість кодів написано, можливо, для десятка людей, які коли-небудь потребують його прочитати, половина з них під час перегляду коду.
corsiKa

4

Навмисне написання помилок, щоб уникнути зарезервованих слів, є поганою ідеєю.

  • Неправильне написання важко відрізнити від правильного написання, тому вони ускладнюють читання коду.

  • Важко запам’ятати написання помилок, тому декілька непослідовних правописів, можливо, змагатимуться в коді, що ускладнює запис і важче читати.

  • Застережені слова відносяться до мови, яка використовується для вирішення проблеми, а не до самої проблеми. Ім'я змінної має вказувати на поняття, пов'язане з проблемою.

Тому краще вибрати альтернативну, описову назву або, якщо не існує задовольняючої альтернативи, кваліфікувати зарезервоване слово як:

public static Method findBenchmarkMethod(BenchmarkRecord benchmark) {
    Class<?> benchmarkedClass = ClassUtils.loadClass(benchmark.generatedClass());
    return findBenchmarkMethod(benchmarkedClass, benchmark.generatedMethod());
}

3

Class clazzпахне на кшталт "я не потрудився спробувати придумати гарне ім'я". Змінна завжди щось представляє, і добре ім'я це описує. Я відмовляюся уявляти, що, clazzнаприклад, за будь-яких обставин є найкращим можливим ім'ям. Це посилання на клас -> class_reference, це копія об'єкта класу -> class_copy і т. Д. Можливо, також випадає "клас" і просто використовується описове слово, наприклад

java.lang.SecurityManager.checkMemberAccess(Class<?> clazz, int which)
Parameters
    clazz -- the class that reflection is to be performed on.

Тут clazz - цільовий клас, на якому слід перевірити, так що

checkMemberAccess(Class<?> target, int which)

Набагато краще б описати, для чого використовується параметр, ніж завжди буде clazz.


IMHO це не краще, ви можете назвати це "classToBeAccessed" або будь-що інше, але будь-яке більш описове ім'я просто показує очевидне. Мені подобаються довгі імена, лише якщо вони надають корисну інформацію.
maaartinus

1
classToBeAccessedце справді хороше ім’я ( classToBeCheckedможливо, було б навіть краще).
hlovdal

1

Якщо вони використовують зарезервоване ім'я для змінної, це змінна назва з поганим іменем. Навіть якщо це законне ім'я, наприклад, Class для програмного забезпечення для аудиторії.

Неправильно названі змінні є ознакою погано продуманого або випадкового коду - остерігайтеся інших ґутчей у тій частині програмного забезпечення, яку ви підтримуєте.


0

Я вважаю, що навмисні написання помилок або скорочень є гарною ідеєю, якщо їх використовувати обережно і послідовно .

Розглянемо на Java:

class X { public X() { } }
X x = new X();
x.getClass;  // Wha?  How does "get" help anything?
x.class;     // Best, but requires more lexer/parser work
x.klass;     // At least as good as getClass
x.clazz;     // Same

Місце використання неправильних написань - це те, де зарезервоване слово - це найкраще слово для роботи. Існує два місця, щоб не використовувати неправильних написань, де вас можуть спокусити.

  1. Вам не здається думати про хороше ім’я
  2. Вам просто потрібна фіктивна змінна, і вона не потребує описової назви

У першому випадку цілком очевидно, що лінь рідко є доброю політикою створення коду якості. У другому випадку виберіть дійсно коротку змінну. Так роблять математики весь час, а програмісти - для індексів. Немає жодних причин обмежувати це робити індексами, якщо це дійсно лише фіктивна змінна:

boolean isMyName(String testName) { return myName.equals(testName); }
boolean isMyName(String s) { return myName.equals(s); }

Date nextMeeting(Klass klass) { return /* something */ }
Date nextMeeting(Klass k) { return /* something */ }

Ви нічого не втрачаєте з короткими назвами змінних, коли метод або структура коду повідомляє вам, що там має бути.


2
Вибачте, я не можу погодитися. Як саме працює nextMeeting? Логіка незрозуміла. Ви змушуєте мене шукати визначення Klass кожного разу, коли я читаю ваш код, оскільки ім'я безглуздо. Якби натомість у вас був nextMeeting (MeetingRoom meetingRoom), я мав би одне визначення менш класу (klass? Clazz?) Для читання і тим самим був би більш продуктивним. Код читається набагато більше, ніж написаний.
MrFox

@suslik - nextMeeting(MeetingRoom r)це багато. Що meetingRoomтебе туди добирає? Якщо nextMeeting(int meetingRoom)я був би я зрозумів, але мій погляд на використання коротких імен змінних, коли інформація вже доступна з інших джерел .
Рекс Керр

У моєму дописі було більше про існування Klass у кодовій базі. Іноді я погоджуюсь з короткими назвами змінних, але якщо ваші методи довгі, і вам доведеться продовжувати обертовувати, щоб переконатися, що "r" є MeetingRoom, то це теж не чудово. Мені цікаво, в чому полягає мінус зустрічіRoom? Горизонтальний простір? Занадто довго вводити текст?
MrFox

@suslik - Так, ви втрачаєте горизонтальний контекст з довгими назвами змінних. Ви втрачаєте вертикальний контекст довгими методами, тому краще спробувати уникати цих (але я згоден, якщо ви все-таки це зробите, ви, мабуть, хочете, щоб ваші імена змінних були кращими нагадуваннями). Klassбула альтернативою, коли було застережене слово . Я не рекомендую використовувати неправильну написання, коли доступний оригінальний правопис!
Рекс Керр

0

Я бачив законні способи використання Class klassрефлексії, де ви дійсно працюєте з екземпляром Classкласу.


2
Питання полягає не в тому, чи є випадок, коли у вас є екземпляр, а в тому, чи слід використовувати це написання, або більш описову назву, таку userClassчи якусь іншу опцію.
Ніколь

2
У такому випадку я вважаю classInstanceза краще klass.
Конрад Моравський

2
@KonradMorawski: Але всі об'єкти, з якими ви працюєте, - це екземпляри, тому вони classInstanceє зайвими. Більше того, я міг уявити щось подібне class klass; Object classInstance = klass.newInstance;.
maaartinus

0

Я часто бачу код, який включає навмисні написання загальних слів, які на краще чи гірше стали зарезервованими словами:

klass або clazz для класу: Class clazz = ThisClass.class

kount для підрахунку в SQL: count (*) AS kount

Особисто я вважаю, що це зменшує читабельність. У власній практиці я не знайшов занадто багато випадків, коли не можна було використовувати кращу назву - itemClass або recordTotal.

Однак це так часто, що я не можу не задатися питанням, чи я єдиний? Хтось має поради чи ще краще, цитував рекомендації від шанованих програмістів щодо цієї практики?

Для локальних змінних та формальних аргументів це просто не має значення.

Будь-яке ім’я чудово, доки воно не буде навмисно вводити в оману чи дратує. У вашому прикладі:

public static Method findBenchmarkMethod(BenchmarkRecord benchmark) {
    Class<?> clazz = ClassUtils.loadClass(benchmark.generatedClass());
    return findBenchmarkMethod(clazz, benchmark.generatedMethod());
}

не має значення, чи є єдиною локальною змінною "clazz" або "klass" або "cls" або просто "c". Я, мабуть, просто накреслив вираз:

return findBenchmarkMethod(ClassUtils.loadClass(benchmark.generatedClass()),
                           benchmark.generatedMethod());

Довжина імені змінної повинна бути пов'язана з областю змінної. Для локальних змінних у коротких методах (і всі вони повинні бути короткими) дуже короткі назви є чудовими.


ваш рядок виглядає неправильним ClassUtils.loadClass(benchmark.generatedClass())=> benchmark.generatedClass()- загублений ClassUtils.loadClassпо дорозі
gnat

0

Я думаю, що неправильно написані слова - це завжди погана ідея. Це просто не приємно вашим читачам. Мені, наприклад, було б цікаво, чи щось я пропустив, коли бачу слово klass. (Чи мали на увазі це class, чи вони мали на увазі пірата?) Принаймні, мені всі правописи, які я визнаю, дратують.

Для тих небагатьох випадків, коли зарезервоване слово справді є єдиним значущим, що відомо про змінну, я б використав такі альтернативи:

  • Якщо це аргумент функції, використовуйте aClassзамість class.

  • Якщо це локальна чи членська змінна, використовуйте myClassзамість class.

  • Якщо це аксесуар, використовуйте getClass()замість class().

Звичайно, доданий префікс є досить безглуздим, і його слід використовувати лише в крайньому випадку. Але принаймні це не заважає розумовому аналізатору вашого читача, і це невдалий спосіб уникнути застережених слів.


0

Однією з переваг творчого написання є краща можливість пошуку. Я думаю, що набагато простіше зробити повний пошук коду унікальних речей, ніж звичайних слів, де занадто часто ви знайдете всі неправильні речі та 1000 їх. Як приклад, я використовував kzpg.com. Google це зараз, і ви побачите лише кілька звернень. Він унікальний і тому дуже досконалий.

Але я вважаю, що це питання є думкою більше, ніж сутністю. Я особисто виріс у Форті, де було все про слова, і їх багато. Один навчився бути дуже креативним, щоб врятувати пальці. Врешті-решт у мене було близько 640 000 символів, більш-менш у моїй джерельній базі. Таким чином, тримати слова короткими було важливо для роботи.


Зараз це посилання розірвано.
Пітер Мортенсен
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.