1. C# / Говнокод #21890

    −20

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    private static Properties[] GetProperty(Properties[] collection, string property, string userName)
    {
        if (collection.Contains(property))
        {
            return collection[property];
        }
        else
        {
            throw new ArgumentException($"Property '{property}' for user '{userName}' was not found");
        }
    }

    А писали-то неглупые вроде люди.

    Запостил: homk, 23 Декабря 2016

    Комментарии (47) RSS

    • неглупо прописал тебе в очко, проверь
      Ответить
    • Это даже не скомпилится
      Ответить
    • > $"Property '{property}' for user '{userName}' was not found"
      Шарпик таки превратили в пыху?
      Ответить
      • есть пароль от гуестноля?
        Ответить
      • Такое не только в пыхе. В петоне, жс точно видел.
        Ответить
        • нет, в петоне не интерполяции
          Ответить
          • Я конечно не пешу на питоне, но это тогда шо?
            https://www.python.org/dev/peps/pep-0498/

            Хз, может нету, но будет
            Ответить
            • А, ну может в 3.6 и есть. Я пользуюсь нормальным петоном (2.7).
              Ответить
              • кросава 👍
                Ответить
              • ты тормозишь прогресс
                пистон 2.7 надо запретить, а таких как ты -- насильно пересадить на 3.6
                Ответить
                • Это петон 3 надо запретить вместе с гвидо. Второй питон идеален. Цирк с переездом всего мира на почти такой же, но несовместимый язык - глупое решение.
                  Ответить
                  • во втором петоне кривой юникод, нету асинкио, нету опт стат тип, и тупое ооп
                    обосцать и сжечь
                    Ответить
                    • > кривой юникод
                      Да и хуй с ним. Байтовые строки - это хорошо (я кретушок).

                      > асинкио
                      Да и хуй с ним. Есть торнадо.

                      > опт стат тип
                      Да и хуй с ним. Даже не знаю, что это.

                      > тупое ооп
                      Нормальное ооп: классы, объекты там. Это же скриптота, зачем там мощные средства для создания абстрактных фабрик интерфейсов?
                      Ответить
                      • Расшифровал, что за опт стат тип. Ну это точно не нужно. Зачем мешать мочу с говном?
                        Ответить
                      • >>Байтовые строки - это хорошо
                        нет

                        >>Да и хуй с ним. Есть торнадо.
                        стандартное лучше кастомного

                        >>Нормальное ооп:
                        (object) ггг

                        >> Ну это точно не нужно
                        а ABC нужны? "string-like classes" нравяца?
                        Ответить
      • это называется стринг интерполейшен
        теперь и в питоне и в котлине и в руби и в перле и в выхе и с решеточке
        Ответить
      • Что плохого в строковой интерполяции?
        Ответить
    • Интересно, а можно напейсать на C++ компайл-тайм интерполяцию строк?
      Вот типа такого:

      int a = 10;
      cout << INTERPOLYACYYA("a: %{a}") << endl;
      Ответить
      • В https://gist.github.com/1024--/d7ac863b94622228beff я реализовал фигню, которая COMPOSE(sqrf2)(x) превращала в sqr(f2(x)) для строк с известной максимальной длиной.
        Т.е. шаблоны могут по строке с известной максимальной длиной парсить и подставлять сущности.
        Только там sqr и f2 у меня были жёстко заданы.
        boost::lambda можно расширять своими оперециями на своих типах: http://www.boost.org/doc/libs/1_60_0/doc/html/lambda/extending.html

        Скажем, у нас есть KEY("abc"), который на самом деле key<'a','b','c'> - точно можно реализовать. Компайл тайм парсинг строки реализовать можно. Для %{abc} построить key<'a','b','c'> наверно можно.
        Для каждого участка строки без форматирования запиливаем insert_string<строка>, для переменных - insert_variable<ключ>. Для конкатенации - concat<x, y>.
        По умолчанию insert_variable<любая фигня>::value будет генерировать ошибку компиляции, а мы, если язык позволяет определить специализацию insert_variable<key<'a','b','c'>>, победим хотя бы в случае с глобальными переменными.
        INTERPOLYACYYA("x: %{x}!") превратится в concat<concat<insert_string<'x',':',' '>, insert_variable<key<'x'>>>, insert_string<'!'>>::to_string()

        // где-то в файле kobenator-interpolacii.h:
        #define BIND_GLOBAL(name) \
        template <> struct insert_variable <KEY(name)> { \
           static const auto& value = name; \
        }
        
        // пользовательский код:
        #include "kobenator-interpolacii.h"
        int x;
        BIND_GLOBAL(x);
        
        int main() {
           cout << INTERPOLYACYYA("x: %{x}") << endl;
        }

        Конечно, может в реальности наткнёмся на подводные камни, но можно попробовать.
        Ответить
        • Если всё это удалось реализовать, можно как костыль добавить рантайм-питушню.
          #define DEFINE_LOCAL(type, name) \
             type name; \
             Variable meta_##name(#name, name);
          
          template <typename key> struct insert_variable {
             string to_string() {
               return variables.get(string_value<key>());
             }
          };

          При создании каждой переменной будет создаваться объект типа Variable, который
          1. будет хранить ссылку на переменную
          2. будет уметь преобразовывать её в строку
          3. в конструкторе зарегистрирует переменную в скопе variables
          4. в деструкторе удалит переменную из скопа variables
          Т.е. в рукотворном динамическом контексте variables будет жить отображение нашей переменной из лексического столько же, сколько живёт сама переменная.

          insert_variable будет доставать переменную из variables.

          variables будет мапой со стеком
          push(name, variable) добавит или перекроет name
          pop(name) откроет предыдущую версию name
          get(name) вернёт текущую Variable для name
          Ответить
          • Хотя, это уже нечестно. Тогда можно вообще на время исполнения перенести.
            Имея зарегистрированные на этапе исполнения переменные, мы просто вызываем функцию от строки, которая их печатает подставляет.
            Ответить
            • Интересно, можно ли без регистрации переменных, которая может привести в питушню этапа выполнения?

              Richard M. Stallman, Zachary Weinberg - The C Preprocessor https://gcc.gnu.org/onlinedocs/cpp.pdf, 3.9 Directives Within Macro Arguments:
              Occasionally it is convenient to use preprocessor directives within the arguments of a macro. The C and C++ standards declare that behavior in these cases is undefined. GNU CPP processes arbitrary directives within macro arguments in exactly the same way as it would have processed the directive were the function-like macro invocation not present.

              Если мы магически сможем обернуть #include в макрос, то создав файлы "a", "b", "c", ..., которые хранят a, b, c, мы получим преобразование символа в токен.
              #define IDENTITY(x) x
              #define INCLUDE(s) IDENTITY( \
              #include s \
              )

              С токенами уже можно работать, определяя фигню вида #define F(x) F_##x, а так же запиливать конкатенацию или преобразовывать в строке.

              Если обернём include, получим INTERPOLATE("x",":"," ","{","x","}","!"), которое преобразуется в фигню вида S0x7e S0x5c ... (с кодами символов, полученных через include), которое преобразуем в "x" ":" " " x "!".
              Ответить
      • что-то не так

        а, точно

        intnya anya = 10nya;
        coutnya << INTERPOLYACNYA("anya: %{anya}") << endlnya;
        Ответить

    Добавить комментарий