2016-03-31 2 views
2

У меня есть сильное чувство в отношении методов, возвращающих несколько результатов для дальнейшего множественного присваивания, например:Возвращает несколько результатов антипаттерн?

class ImportUsersFromFile 
    def perform 
    ... 
    [imported_rows, errors] 
    end 
end 

потому что он вводит неясную и inobvious структуру данных «массив, первый элемент которого является этой вещью, и вторым это что-то другое ». Было бы замечательно, если бы было очевидно, что метод должен вернуть такую ​​структуру. Например, можно ожидать три значения first_name, middle_name, last_name по методу Person#name_parts.

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

+0

Ваш код возвращает массив, который может быть введен в несколько значений с использованием функции «Уничтожение» Ruby. Что случилось с массивом? BTW: Почему бы не поднимать ошибки, а не вводить их в возвращаемые значения? – sschmeck

+0

Я объяснил, что не так с деструкцией массива в этом случае: интерфейс не ясен. Одно дело ожидать, что 'perform' возвращает список импортированных пользователей, а другой - знать, что он действительно возвращает массив из двух списков. Ошибки не возникают в моем случае, потому что они не являются исключительными - если в некоторых строках есть ошибки, другие строки должны быть импортированы в любом случае. – Hnatt

+0

Затем ваш интерфейс метода возвращает два ведра: один с хорошими строками и один с плохим. Это звучит разумно для меня, но не как антипаттерн. Если ошибки не имеют значения, то игнорировать их явно, как 'users, _ = importer.perform'. – sschmeck

ответ

1

Для чего это стоит, я не уверен, что я назвал бы это антипаттерн. Я беру вашу точку зрения, но и за то, что Руби конкретно имеет свой интерпретатор сделку с самим вопросом вы говорите о:

def foo 
    [1,2] 
end 

a = foo # -> a = [1,2] 
a,b = foo # -> a = 1, b = 2 
_,b = foo # -> b = 2 

Так, насколько я понимаю, зная, что метод/функцию возвращает два значения не хуже, чем знать, что вы передать его двух значений.

Сказав это: если это делает вас непримиримым, вы должны, конечно, избегать этого. Там нет ничего плохого.

+0

Моя проблема не может быть проиллюстрирована словами 'foo' и' bar'. Это больше о семантике. Как я уже сказал, я считаю совершенно корректным метод 'Person # name_parts', который возвращает массив из трех значений, порядок которых очевиден от имени, но не столько императивный метод, который выполняет некоторые пакетные действия, но и возвращает числа успехов и неудачи. Входящие параметры (их имена и порядок) можно увидеть в сигнатуре метода. Но чтобы узнать порядок возвращаемых значений, нужно прочитать код метода. Для меня это не удобный интерфейс. – Hnatt

+0

@ Hnatt В Ruby ваш интерфейс идиоматичен, я думаю. Если вам кажется, что это неправильно или пользователи вашего кода, не стесняйтесь его менять. Альтернативами являются пользовательские _Value objects_ или именованные значения, реализованные Ruby 'Hash'. – sschmeck

+0

@ Хнат, простите меня. Но если ваша проблема не может быть проиллюстрирована общим кодом примера («foos and bars») _and_, это проблема семантики, тогда я лично не уверен, что это проблема программирования. Разве это не идиоматично, что проблемы семантического программирования ** могут быть проиллюстрированы примером кода? Опять же: как знать порядок возвращаемых значений, отличный от того, чтобы знать порядок входных параметров? –

Смежные вопросы