LINUX.ORG.RU
ФорумTalks

Программистских баек тред

 ,


0

2

Давайте, что ли, откроем локальный филиал башорга и твиттера на тему разработки. Можно рассказывать занимательные и не очень истории из жизни, байки, мемы и просто «как я провел день».

Начну.

История первая.

У меня кусок админки управляет кучкой фоновых процессов. Не напрямую, а через прослойку-супервизора. Прослойку я написал на PHP, чтобы задействовать уже готовые функции админки. А чтобы управлять фоновыми процессами, потребовалось на php из подручных средств соорудить аналог pidfile_open (3). Вот такой:

function readPidfile($pidfile) {
    /* XXX: Race conditions are everywhere. But who cares? */

    if (!file_exists($pidfile)) {
        /* No such file - daemon not running */
        return false;
    }

    $f = fopen($pidfile, "r");
    if (!$f) {
        /* Failed to open file - daemon probably not running */
        return false;
    }

    if (flock($f, LOCK_EX | LOCK_NB)) {
        /* Able to acuire lock - daemon not running */
        fclose($f);
        return false;
    }

    /* Return PID */
    $pid = fgets($f);
    return $pid;
}

Вот смотрю и думаю: какое-то нецелевое использование «макропроцессора для HTML-страниц». Ну а почему бы и нет. Работает же.

История вторая.

Сегодня пришлось повоевать с кодировками в icecast. icecast к кодировкам оказался не очень приспособлен. Вот написал им, может замерджат мой патч: https://gitlab.xiph.org/xiph/icecast-server/-/issues/2423

Но что-то сомнительно. Ход очевидный, но почему-то сами они его не делали.

Ответ на: комментарий от eternal_sorrow

Ладно ещё кемел кейс, на него я с зажатым носом готов смотреть.

Илитка с утра проснулась. =)

wandrien ★★
() автор топика
Ответ на: комментарий от fernandos

А неоптимизирована она потому, что вместо практически mutation-free получилась слепая функция, которая очищает кэш просто так. Хотя это немного нудная тупая придирчивость.

Первое. Очищает не «кэш», а одну строку кэша.

Второе. Кого вообще должен волновать этот сраный кэш? Всё это явно задумывалось как оптимизация количества сисколов под веб-скрипты. Большой вопрос нужна ли она была в 90-х, а сейчас уже тем более не нужна.

А, и ваш код не сработает, если где-то выше вы заблокируете этот файл.

Потрясающее наблюдение. xD

wandrien ★★
() автор топика
Ответ на: комментарий от fernandos

неоптимизирована

Я тебя сейчас вообще шокирую.

Я везде использую вот такую велосипедную функцию:

$channel_id = arrayGetWithDefault($channel, 'id', false);
$create_new = arrayGetWithDefault($channel, 'create_new', false);

Вместо кривого костыля isset(foo[bar]) ? foo[bar] : "default value"

Потому что главное в любом коде - возможность его чтения, а не «оптимизации», высосанные из пальца.

wandrien ★★
() автор топика
Ответ на: комментарий от wandrien

Вместо кривого костыля isset(foo[bar]) ? foo[bar] : «default value»

Чтобы не использовать костыль ввели целый оператор объединения с нулл.

Потому что главное в любом коде - возможность его чтения, а не «оптимизации», высосанные из пальца.

Ну да.

fernandos ★★★
()
Ответ на: комментарий от wandrien

Первое. Очищает не «кэш», а одну строку кэша.

Да.

Второе. Кого вообще должен волновать этот сраный кэш?

Разработчиков cli-утилит волнует, что надо использовать костыли.

fernandos ★★★
()
Ответ на: комментарий от wandrien

snake+lower же. И то не факт, что под pidfile не понимается одно понятие.

fernandos ★★★
()
Ответ на: комментарий от wandrien

http://sandbox.onlinephpfunctions.com/code/54b09dbae918c9ae6d542714afaa0795a64c6204

Это именно замена проверки на существование переменной (или значение нулл) с последующим выбором значения по умолчанию.

Вот, короче.

https://www.php.net/manual/ru/migration70.new-features.php#migration70.new-features.null-coalesce-op

оно всё равно даст ворнинг

Вы даже если будете использовать неинициализированную переменную, уровень ошибки будет 8, а не 3.

fernandos ★★★
()
Последнее исправление: fernandos (всего исправлений: 2)
Ответ на: комментарий от wandrien

Если смущает только Warning - есть же тупо собачка '@' для этого. $f = @fopen("nosuchfile", "r");

Toxo2 ★★★
()
Ответ на: комментарий от WitcherGeralt

Раз уж начал, давай, что-нибудь поинтересней расскажи

у меня в одном из легаси-проектов есть математика на эксепшенах.

есть отдельный счетчик эксепшенов и есть проверка. если эксепшенов меньше трех, то еще туда-сюда, а вот если больше…

Rastafarra ★★★★
()
Ответ на: комментарий от Rastafarra

Напомнил мне мои времена школоло-разрабоики jabber-ботов. Практически у всех ботов тогда бы команда «тест» для проверки, не висит ли он. Мой в зависимости от количества ошибок отвечал разное, а в худшем случае «со мной всё кончено, бро, спасайся, я задержу их».

WitcherGeralt ★★
()
Ответ на: комментарий от stevejobs

Denо для скиптинга интереснее.

На нем даже шелл сдетали.

grim ★★☆☆
()

Подниму тред. Свежих баек у меня снова нет, поэтому поделюсь еще парой кусков кода, которые я сегодня наговнокодил.

Первая - аналог PHP-шной escapeshellarg() на крестах:

std::string escapeshellarg(const std::string &str)
{
  std::string result;

  if (str.size() == 0) {
    result = "\'\'";
    return result;
  }

  int estimated_size = 0;
  for(const char& c : str) {
    if (c == '\'')
      estimated_size += 4;
    else
      estimated_size += 1;
  }

  result.reserve(estimated_size);

  bool inside_quotes = false;
  for(const char& c : str) {
    if (c == '\'') {
      if (inside_quotes) {
        result += '\'';
        inside_quotes = false;
      }
      result += "\\\'";
    } else {
      if (!inside_quotes) {
        result += '\'';
        inside_quotes = true;
      }
      result += c;
    }
  }

  if (inside_quotes) {
    result += '\'';
    inside_quotes = false;
  }

  return result;
}

#ifdef INSIDE_CATCH

struct TestStringPair {
  const char * str;
  const char * result;
};

TEST_CASE( "escapeshellarg") {

  auto testData = GENERATE(
    TestStringPair {"", "\'\'"},
    TestStringPair {"\'", "\\\'"},
    TestStringPair {" ", "\' \'"},
    TestStringPair {"\"\"", "\'\"\"\'"},
    TestStringPair {"\'a", "\\\'\'a\'"},
    TestStringPair {"a\'", "\'a\'\\\'"},
    TestStringPair {"a b c \'\'\' 1 2 3", "\'a b c \'\\\'\\\'\\\'\' 1 2 3\'"},
    TestStringPair {"/abc/d/", "\'/abc/d/\'"}
  );

  REQUIRE(escapeshellarg(testData.str) == std::string(testData.result));
}

#endif

Не нашел готовой стандартной функции на это. Может плохо искал.

А вторая – ради чего была написана первая. Поставляет в указанную строку указанные переменные.

std::string substitute_prefixed_variables(const std::string &str, const std::map<char, std::string> &variables, char prefix, bool escape_for_shell)
{
  std::string result;
  result.reserve(str.size() * 2);

  bool in_prefix = false;
  for(const char& c : str) {
    if (in_prefix) {
      if (c == prefix) {
        result += c;
      } else {
        auto search = variables.find(c);
        if (search != variables.end()) {
            if (escape_for_shell) {
              result += escapeshellarg(search->second);
            } else {
              result += search->second;
            }
        }
      }
      in_prefix = false;
    } else {
      if (c == prefix) {
        in_prefix = true;
      } else {
        result += c;
      }
    }
  }

  return result;
}

#ifdef INSIDE_CATCH

struct TestData {
  const char * str;
  bool escape_for_shell;
  const char * result;
};

TEST_CASE( "substitute_prefixed_variables") {

  auto testData = GENERATE(
    TestData {"/abc/d%% %1 %2 %3", false, "/abc/d% file file \' "},
    TestData {"/abc/d%% %1 %2 %3", true, "/abc/d% \'file\' \'file \'\\\' \'\'"},
    TestData {"", true, ""},
    TestData {"%1", true, "\'file\'"},
    TestData {"%%", true, "%"}
  );

  std::map<char, std::string> variables{
    { '1', "file"},
    { '2', "file \'"},
    { '3', ""},
  };

  REQUIRE(
    substitute_prefixed_variables(testData.str, variables, '%', testData.escape_for_shell)
    ==
    std::string(testData.result)
  );
}

#endif

Критикуйте. =)

wandrien ★★
() автор топика
Последнее исправление: wandrien (всего исправлений: 2)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.