Здравствуйте, Vzhyk, Вы писали:
EP>>Если тебе нравится вариант с goto, если тебе он кажется более понятным — используй его, не комплексуй (конечно если в твоей команде нет каких-то жёстких guidelines на эту тему). V>Только вот, если побьют потом, пенять будет он на себя.
Так ведь за битого двух небитых дают
V>В коде по смыслу цикл, даже его метка об этом говорит, зачем код извращать на сокрытие цикла? Чтоб никто не догадался?
По смыслу там действительно цикл. Я о том, что пусть делает так как ему нравится.
Я бы наверное весь control flow отделил бы от логики:
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>наверняка многие сталкивались с подобным сценарием когда думаешь искусственный J>цикл или goto...
J>есть некая функция которая скачивает из интернета файл J>иногда сервер закрывает соединение не отдав весь файл J>я делаю новый запрос с полем Range: дабы докачать "хвост" J>и иногда сервер отвечает кодом 404 Not Found у меня вылетает исключение J>которое надо перехватить на месте получить новую ссылку на этот же файл J>и докачать файл
А цикл же всё равно нужен, чтобы ограничить количество попыток скачивания.
Псевдопитонокод:
def get_http_chunk(params, offset):
for i in range(MAX_RETRIES_ON_404):
try:
link = generate_link(params)
http_response = do_http_request(link, headers = { "Range": "bytes={}-".format(offset) })
total_length = get_total_length_from_content_range_header(http_response)
return http_response.data(), total_length
except HttpError as e:
if e.code != 404:
raise
raise NuNeSmogla()
def get_file(params):
data = bytearray()
for i in range(MAX_DOWNLOAD_ATTEMPTS):
new_data, total_length = get_http_chunk(params, offset=len(data))
data.append(new_data)
if len(data) == total_length:
return data
raise NuNeSmogla()
и безо всяких искусственных control flow statements.
Код с goto потом будет труднее поддерживать. Например, захочешь прикрутить то же ограничение количества попыток, и куда тебе ставить это ++i? Или запись в лог после неудачной попытки, особенно в случае, когда goto repeat будет несколько?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>я так понимаю вы имеете ввиду что то вроде этого ?
Зачем так сложно? просто будет объект, в полях которого будет контекст, а функции "сгенерировать ссылку", "докачать из текущей", "скачать из текущей" и т. п. будут его методами...
То есть клиентский код будет типа строить экземпляр такого объекта и звать у него метод "скачай", метод будет возвращать скачал ли он в конце концов или ничего не будет возвращать. А внутри он будет иметь цикл, например такой :
Всё будет просто, понятно, и контекст копировать не надо будет, он будет просто в полях объекта лежать...
Но если охота, то можно, конечно, и в лямбду поля завернуть.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>заводить отдельный класс для неявной передачи контекста между двумя функциями
Это не неявная передача контекста, это реализация всего функционала по скачиванию файла. Пространство имён и структура с контекстом в одном флаконе...
Ты же всё равно заводил бы какую-то функцию для этого дело? На у тут будет не функция в глобальном пространстве имён, а объект-механизм. В чём принципиальная разница? Зато он инкапсулирует все потроха...
J>вместо одного goto ...
Я конкретно в этом случае не вижу проблемы от готу. Правда мне так кажется, что если всё делать через циклы, то выходит лучше, но и с гото код понятный.
Другое дело, если у тебя часто возникает нужда в гото, это нехороший признак...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Evgeny.Panasyuk, Вы писали:
J>>если честно с goto мне тоже нравится J>>ой рискую я сейчас наставят мне минусов
EP>Если тебе нравится вариант с goto, если тебе он кажется более понятным — используй его, не комплексуй (конечно если в твоей команде нет каких-то жёстких guidelines на эту тему).
Печаль про goto в том, что с ним легче в дедлок угодить и логику запутать, но если использовать его по месту, то всё ок. Откуда взялись все эти "нельзя!", непонятно... сдаётся мне, не обошлось очередной методологией ради методологии.
Здравствуйте, CEMb, Вы писали:
CEM>Печаль про goto в том, что с ним легче в дедлок угодить и логику запутать, но если использовать его по месту, то всё ок. Откуда взялись все эти "нельзя!", непонятно... сдаётся мне, не обошлось очередной методологией ради методологии.
Вообще правило одно, если тебе захотелось использовать goto, подумай 7 раз почему и нет ли более понятного решения без goto.
вся проблема в исключениях, они не нужны в read_internet_file. Вот так бы это выглядело с кодами возврата:
for ( result = read_internet_file(generate_link());
result == http_code::not_found;
result = read_internet_file(generate_link()) )
{
log( "Yet another try..." );
}
if ( result != http_code::ok200 )
throw http_exception( result );
A>for ( result = read_internet_file(generate_link());
A> result == http_code::not_found;
A> result = read_internet_file(generate_link()) )
A>{
A> log( "Yet another try..." );
A>}