Можно ли предотвратить смерть скобками? - PullRequest
6 голосов
/ 26 августа 2011

Иногда я пишу код с большим количеством скобок, чем мне нравится.

 if(!(new Day((((new Date()) / millisecondsPerDay) % 75)) instanceof oldDay))) { 
    // Bonus points if that condition made any sense to you
 }

Трудно отследить, сколько скобок мне нужно поставить, особенно когда я не использую IDE, которая немедленно сообщает мне, когда что-то не так. На самом деле, я держу пари, что приведенный выше пример неправильно соответствует скобкам. Скобки со мной связывают ошибки смерти больше, чем я хотел бы признать.

Мне было интересно, есть ли способ обойти это. Какие приемы я могу использовать, чтобы избежать необходимости заключать много скобок в скобки?

Существуют ли языки с механизмом, который предотвращает необходимость в таком количестве скобок? Например, я подумал, что может помочь добавление специальных символов, которые автоматически закрывают скобки, и символы, которые автоматически их открывают. (< и > в следующем примере)

if(!(new Day<new Date()) / millisecondsPerDay) % 75> instanceof oldDay>

Ответы [ 5 ]

9 голосов
/ 27 августа 2011

Одной из жизнеспособных альтернатив является предварительное вычисление значений в скобках перед условным циклом.Возьмите ваш код, например:

if(!(new Day((((new Date()) / millisecondsPerDay) % 75)) instanceof oldDay))) { 
    // Bonus points if that condition made any sense to you
 }

Давайте начнем разбивать его.

Date d1 = new Date();
var factor1 = (d1 / millisecondsPerDay ) % 75;
Day day1 = new Day (factor1);

if (!day1 instanceof oldDay) {
// do something
}

Помните, что код написан для людей, чтобы читать и только потом для машин, чтобы выполнить.Если вы найдете гигантские условия, то начните их предварительную обработку и разбейте.Если для выяснения того, что проверяет ваше состояние, требуется больше секунды, тогда, вероятно, это слишком долго.

2 голосов
/ 27 августа 2011

Ну, во-первых, мне всегда нравится рефакторинг такого рода кода. Если я могу, я извлекаю часть выражения в переменную (или функцию, в зависимости от того, что лучше всего подходит), тогда вы можете иметь больше смысла для самого кода, и вам не нужно будет создавать такой беспорядок

bool isOldDay(int someFactor)
{
    if(someFactor instanceof oldDay) 
    {
        return true;
    }
    return false;

}

var today = new Date();
var particularFactor = today/millisecondsPerDay;
var someFactor = particularFactor % 75
var day = new Day(someFactor);


if(!isOldDay(day)) //Do something

РЕДАКТИРОВАТЬ: Кстати, если вы хотите сделать что-то без скобок, вы можете попробовать что-то вроде этого: Обратная польская запись

Что вы можете сделать 5 + ((1 + 2) * 4) − 3 в этой вещи: 5 1 2 + 4 * + 3 -. Конечно, эта форма может быть очень близка к представлению вычислений в компиляторах.

1 голос
/ 27 августа 2011

То, что столько паренов - довольно хороший признак того, что

  1. Автор не понимает операторский приоритет языка. Например, вы завернули вызов конструктора new Date() в полностью избыточный набор скобок (new Date()). Если ваш язык не отличается от любого обычного языка, этот префиксный оператор new будет связываться крепче, чем почти любой другой оператор.

  2. Автору наплевать на понятность.

Сделайте его более понятным, проверяемым и поддерживаемым. Кто-то в дальнейшем (кто может быть вами, поблагодарит вас за это ... или проклянет вас за то, что вы этого не сделали).

Некоторые подсказки:

  • Понять приоритет оператора вашего языка. Не добавляйте скобки без веской причины. Кто-то, кто понимает приоритет операторов, должен потратить некоторое время на выяснение , почему вы помещаете эти символы: вы делаете здесь что-то неочевидное?

  • Разбить выражение. Используйте пространство стека (это дешево).

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

  • заставляет имена переменных отражать то, что они представляют.

Тогда тестируйте только последний временный. В вашем случае это выглядит как логическое значение.

Написание подобного кода облегчает понимание (нет сложных выражений), упрощает тестирование (простые выражения гораздо проще проверять на правильность). Это облегчает выявление / обнаружение проблем.

1 голос
/ 27 августа 2011

Если я следую:

var a = new Date() / millisecondsPerDay) % 75
var newDay = new Day(a);

if (! newDay instanceof oldDay) {
   //do something
}

Если вы не можете прочитать встроенную логику ... просто поместите ее в несколько строк! ; -)

0 голосов
/ 27 августа 2011

Я бы сказал, что ответ на этот вопрос - НЕТ, потому что весь смысл всех этих скобок состоит в том, чтобы избежать двусмысленности в выражении.Если вы удалите их, выражение может быть оценено не так, как вы думаете.

Ergo, если существовала такая конструкция, как <>, для исправления / добавления отсутствующих паренов, если не может добавитьих в том месте, где вы ожидали.

Простой пример (как если бы он был необходим):

(90 / 100 - 1)

... будет оцениваться как ...

((90 / 100) - 1) // = -0.1

... или ...

(90 / (100 - 1)) // = 0.90909090...

... и у вас нет реального способа узнать, какой это будет.

Единственная альтернатива - переместитьиз частей вне вашего выражения сохраните результаты в переменных, чтобы вы могли меньше оценивать их.

...