Кресты / Говнокод #27454 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
#include <iostream>
using namespace std;

int main() {
	const char *kakoiBagor = R""""(
"Какой
багор )))"
)"""";
	cout << kakoiBagor << endl;
	return 0;
}

А вы знали, что в C++ есть ХЕРЕДОК?

https://ideone.com/5KdJJQ

Запостил: 3_dar 3_dar, (Updated )

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

  • Что такое «ХЕРЕДОК»? Про многострочные строки я уже давно знал: в них писал асмовставки для «gcc».
    Ответить
    • В перле так называли многострочные строки. Или даже в шелле это началось...
      Ответить
      • А в «Nim» оно называется «дедент».
        import strutils
        proc foo =
          let str = dedent """
            Hello
              World!
          """
          stdout.write str
        
        foo()
        Ответить
        • Почему? ) Зачем такая избыточность, уже же тройные кавычки
          Ответить
          • Погуглил, довольно красивое и логичное название: «dedent» – это абзацный отступ.
            Ответить
            • Это поди просто функция, которая срезает лишние отступы в начале строк? Т.е. кавычки и без dedent нормально отработают, но там будут лишние пробелы в начале.
              Ответить
              • Да, я сейчас проверил, ты прав! Спасибо за пояснение. Как я понимаю, она ищет минимальное количество пробелов и всякой фигни в начале очередной строки, а потом у каждой строки с начала убирает это количество пробелов.

                Кстати, это компайл-тайм функция!
                Ответить
                  • При этом в «Nim» её просто написали и теперь всё хорошо. А вот в питоне такая функция будет вызываться каждый раз, когда ты инициализируешь многострочную строку, пока Великий Гвидо не соизволит эту функцию добавить в стандартную либу и как-то так её реализовать, чтобы она раскрывалась типа как мокрос (чего не будет никогда uwu).
                    Ответить
              • >росто функция, которая срезает лишние отступы
                извините
                petuh(`m4')dnl
                Ответить
            • То есть например кейворд new или пистонья lambda — это избыточно, а dedent ради мультилайна, при этом в тройных кавычках — это норм? Или у тебя по поводу первых двух иное мнение?

              Кстати, пистону бы пошло добавить dedent
              Ответить
              • > То есть например кейворд new или пистонья lambda — это избыточно

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

                >new
                говно и ненужен. От него только вред, потому что он засирает код

                >lambda
                это соль, чтобы не хотелось её писать
                Ответить
                • > new

                  Как ты обозначишь каким образом и где создать объект?

                  > Ки

                  Кейворд уже устоявшееся выражение. Типа как суши (правильно говорить – суси).

                  > lambda

                  Есть такая картинка с лесом и надписью: «не нашел снайпера за 5 секунд – проиграл», лямбда без кейворда точно так же прячется в скобочках и загогулинах, как снайпер в комуфляже в зарослях.
                  Ответить
                  • >Как ты обозначишь каким образом и где создать объект?
                    А в каком языке, кроме С++, у тебя есть выбор?

                    > устоявшееся выражение.
                    угу, как "колготки с лукрой'

                    >прячется в скобочках и загогулинах,
                    но почему она не прячется в руби или котлине или JS?
                    Ответить
                      • ну в питоне тебе хорошо без "new"?
                        Ruby
                        [1, 2, 3].select{|n| n % 2 == 0}

                        JS
                        [1,2,3].filter(n=> n %2 == 0)

                        Perl
                        grep {$_ % 2 == 0} (1,2,3)

                        Kotlin
                        (1..3).filter {it % 2 == 0}

                        Groovy
                        [1,2,3].findAll {it % 2 == 0}


                        Все скриптушки боль-мень консистненты, только питухон выделяетчя
                        Ответить
                        • В пистоне new не страшно было бы, по сравнению с тем, что там this надо первым параметром в методы передавать явно
                          Ответить
                        • > ну в питоне тебе хорошо без "new"

                          Плохо, мне он вообще не очень нравится, просто я хочу быстро заработать много денег, создавая сайт на «джанге».

                          > {{ куча лямбд }}

                          Мне они все не нравятся тем, что если бы в функцию передавались несколько результатов выражений, пара лямбд и ещё какие-нибудь параметры-массивы, то вызов функции превратился бы в кашу из специальных символов:

                          funkcia([n % n == 2 for n in {} + {11 % 2}], (1, 2 + 3, "$s" % 8) ...)

                          Что-то типа такого. Лично мне неприятно разбирать штучки!

                          Вот в «Nim» всё по-ня-тно, там лямбда выглядит так:

                          do (x: int) -> bool: x == 5

                          Сразу видно где лямбда начинается, где у неё аргумент, где у неё возвращаемое значение и что она делает. Ещё лямбду можно объявить как процедуру, это ещё нагляднее!

                          В «Nim», кстати, есть «new», мне такое по нраву: можно создать объект в куче!
                          Ответить
                          • >Плохо, мне он вообще не очень нравится, просто я хочу быстро заработать много денег

                            Изучи PHP! Там есть new!

                            > бы в функцию передавались несколько результатов выражений
                            >пара лямбд и ещё какие-нибудь параметры-массивы,
                            если у тебя функция c несколькими аргументами, пара из которых другие лямбды, то не нужно делать лямбду наверное


                            > можно создать объект в куче!
                            а на стеке?
                            Ответить
                            • > а на стеке?

                              И на стеке!

                              > Изучи PHP!

                              Нехочетсо.

                              > то не нужно делать лямбду наверное

                              Если обозначение лямбды понятно и выделяется, то почему бы и нет.

                              Например, можно передать в функцию компаратор и ещё одну лямбду, которая будет какой-нибудь массив записывать в файл.
                              Ответить
                    • > в каком языке, кроме С++, у тебя есть выбор?

                      JS
                      Ответить
                        • В JS есть разница между "new" и не "new", но к расположению в куче/стеке это отношения не имеет
                          Ответить
                          • А где тебе больше нравится располагать всякую фигню: в куче или на стеке?
                            Ответить
                            • На стеке, если я не собираюсь пользоваться ею после завершения функции, и если она не весит гигабайт конечно
                              Ответить
                              • Полностью с тобой согласен. Вообще я за «RAII», поэтому я за размещение на стеке кучи обёрток над ресурсами, которые лежат где-то в куче или вообще не занимают памяти.
                                Ответить
                                • > которые лежат где-то в куче
                                  Ну это не всегда хорошо.

                                  Зачем мне хранить в куче три инта?
                                  Кстати, а можно сделать такую оптимизхацию, чтобы sizeof(vector<int>) занимал бы столько, чтоб можно было прямо в нем хранить 1-2 инта, а что больше -- класть в кучу
                                  Ответить
                                  • По стандарту нельзя.
                                    // Предположим, что вектор хранит до 10 элементов в себе
                                    std::vector a = {0, 1, 2, 3, 4, 5, 6};
                                    std::vector b = {0, 1};
                                    int* c = &a[5];
                                    std::swap(a, b);
                                    /* c должно указывать на валидный элемент:
                                    no swap() function invalidates any references, pointers, or iterators referring to the elements of the containers being swapped. */
                                    Ответить
                                    • а если у них разные аллокаторы, то как оно будет работать?
                                      или их тогда нельзя swap?
                                      Ответить
                                      • Если у аллокаторов propagate_on_container_swap включён, то они и аллокаторами поменяются. А если нет, то если аллокаторы разные — UB.
                                        Ответить
                                        • > А если нет, то если аллокаторы разные — UB.

                                          Тогда значит я в теории мог бы сделать такой аллокатор, который первые N хранил бы на стеке не сломав swap

                                          или всё равно не мог бы?

                                          Походу не могу еще потому что стандартные коллекции (емнип) просто вызывают ему методы чтобы создать и удалить объект, а на их размер он не влияет..
                                          Ответить
                            • https://learn.javascript.ru/constructor-new

                              "new" при вызове функции неявно создает "this" и его же возвращает.

                              Для примитивных типов String (в JS это примитив), Integer и пр. вызов их без new это просто каст, а с new создание объекта-враппера.

                              По степени упоротости приблежается к перловому bless, который привязывает ссылку к пакету, реализуя таким образом объект)
                              Ответить
                                • Верно.
                                  new Boolean(false)

                                  это объект, а в булевом контексте он true:)
                                  Ответить
                                  • И потом ЭТИ ЛЮДИ говорят что в «С++» что-то там в ногу стреляет.
                                    Ответить
                                    • У JSа есть своя пушка для стреляния в ногу, не хуже крестовой.
                                      Она стреляет ``[object Object]``ом и "undefined"ом
                                      Разницей между "of" и "in" в лупе.
                                      Ловким приведением типов
                                      итп
                                      Ответить
                        • Выстреливать в колено или нет.
                          Ответить
                          • а нук, бойцы, чем в JS отличаются эти две строчки (без заглядывания в доку)
                            const a = String(foo);
                            const b = new String(foo);
                            Ответить
                  • Со стрелочной функцией лямбда прекрасно читается, а в чем смысл её непосредственно искать, а не просто прочесть и понять при встрече?

                    Так в коде теряется всё вообще)
                    Её естественно лучше выделить отступами, каментами и так далее, если вдруг почему-то в твоём коде лямбда - это что-то необычное, что может понадобиться "искать".
                    Ответить
                  • Какой конструктор вызван, тот и работает, результат его работы - ссылка на объект. Имя конструктора = имя класса.

                    Достаточно mySecondEblan = Pituh(2, "eblan"). Нахуй new в таких языках как js, Java, сисярп? Ни нахуй он не не нужон
                    Ответить
                    • В сисярпе new явно вызывает конструктор, а иначе как ты отличишь, например, в каком-либо методе класса Koorochka, обращаешься ты к конструктору класса Pituh или к методу Pituh(int i, string s), определенному в классе Koorochka? Но в коко, кстати, обошлись без new.
                      Ответить
                      • Потому что в сишарпе методы начинаются с большой буквы, как и конструкторы. Такой проблемы в java/koko нет.

                        Но вообще нужно было просто делать синтаксис как в C++, и проблемы бы не было

                        Petuh p(1,"A");


                        Весьма очевидно, что ты вызвал.

                        А еще в C# "new" вызывает конструктор даже у распологаемых (по умолчанию) в стеке структурах, что особо пиздец
                        Ответить
                        • >
                          Petuh p(1,"A");

                          Я не понял, что ты проиллюстрировал этим кодом
                          Ответить
                        • > Такой проблемы в java нет.
                          Проблемы нет, а new есть.
                          > А еще в C# "new" вызывает конструктор даже у распологаемых (по умолчанию) в стеке структурах, что особо пиздец
                          Почему пиздец? В C# new означает вызов конструктора, только и всего, это же не C++.
                          Ответить
                          • >Проблемы нет, а new есть.
                            потому что джавушки пидарасы

                            Впрочем, в крестах тоже можно соснуть и написат

                            foo = Foo(123);
                            но это более редко

                            Забавно, что new есть еще в Ruby, но там оно метод класса.
                            И еще в objc, не к ноче будет помянут
                            Ответить
                        • > делать синтаксис как в C++

                          Ты действительно хочешь синтаксис "как в с++"? 😉

                          Там ведь помимо Petuh a(1, "A") можно и Petuh(1, "A") написать для создания временного объекта на стеке. И Petuh{1, "A"). И Petuh p = {1, "A"}. Возможно я ещё какие-то варианты забыла, лол.

                          Но, с другой стороны, там всё просто. Что ближе по скопу, то и вызовется. Т.е. метод своего класса победит конструктор другого класса.
                          Ответить
                          • > Возможно я ещё какие-то варианты забыла, лол.

                            И причём у этих вариантов может, сука, быть разное поведение!
                            Ответить
                            • > разное поведение

                              А самые неудачные из них вообще декларируют функцию, а не создают объект...

                              "Нужно было просто делать синтаксис как в C++, и проблемы бы не было".
                              Ответить
                              • Блин, ну в C# не так определяются ссылки на функцию (там delegate для этово)

                                неужели не было бы лучше вместо
                                var kakashka = new Kakashka();

                                писать
                                Konfetka konfetka();

                                ?

                                Тут правда есть такой жмых, что без скобочек бы оно просто создавало указатель (в случае референс тайпа)
                                Ответить
                                • Я за var kakashka = Kakashka(). Нафиг там new, если без него всё равно не работает. И никакой путаницы между пустым референсом и созданием объекта без аргументов не будет.
                                  Ответить
                                  • Ну вот у Эукариота был такой аргумент, что ``Kakashka`` может быть методом в твоем классе

                                    в C# же методы пишутся с большой буквы
                                    Ответить
                                    • Да ничем, но это удобнее для автоинициализации пропертей при создании экземпляра класса:
                                      class A
                                      {
                                          //раньше было только так:
                                          public Dictionary<string, string> Dictionary { get; set; } = new Dictionary<string, string>();
                                          //а теперь можно так:
                                          public Dictionary<string, string> Dictionary { get; set; } = new();
                                      }
                                      Ответить
                                    • std::any ?


                                      В C# кстати есть "dynamic" -- вообще отказ от стат типизации, как "any" в TS или "def" в груви
                                      Ответить
                                      • Но реально юзать можно только после каста во что-то конкретное, как в крестах?
                                        Ответить
                                        • dynamic то?

                                          Вроде нет, ты просто дергаешь метод, и течешь.
                                          Он дергает его рефлексией, так что кастить ничего не нужно.

                                          Опкод в IL ввели небось для скриптушни типа Ironpython
                                          -------
                                          пруупф
                                          //
                                              class SomeClass
                                              {
                                                  public string Name = "foo";
                                              }
                                          
                                              class AnotherClass
                                              {
                                                  public string Name = "foo";
                                              }
                                          
                                              class Class1
                                              {
                                                  public static void Main(string[] args)
                                                  {
                                                      dynamic foo;
                                                      foo = new SomeClass();
                                                      Console.WriteLine(foo.Name); //ok
                                                      foo = new AnotherClass();
                                                      Console.WriteLine(foo.Name); //ok
                                                      Console.WriteLine(foo.Ooops()); //Эксепшен будет
                                                  }
                                              }
                                          Ответить
                                          • ну да, object же это по сути "void*"

                                            А как работает object для value types?
                                            или никак?
                                            Ответить
                                              • Пнятненько.

                                                То есть если нечто принимает "object" в качестве аргумента, то передача туда даже обычного числа "1" приведет к перемещению этого числа в кучу (ну или взятию из пула, наверное) и к передаче ссылки на него?

                                                Ох.. Слава богу, в c# для этого генерики есть
                                                Ответить
                                                • Так и есть. При этом, если в этом методе object кастуется обратно в int, то это число из кучи скопируется в стек. Всё это не бесплатно, разумеется. Так себе удовольствие, в общем.
                                                  Ответить
                                                  • В джаве так же.. С той только разницей, что генериками это вообще не решить(
                                                    Ответить
                                    • С var естественно так нельзя, как компилятор тип-то выведет?
                                      Ответить
                                            • Хиндли и Милнер ставят лайк.

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

                                              Алсо, нужна же наверное структутрная типизация?
                                              Ответить
                                              • Ну тут скорее с "методами" проблемы будут.

                                                Вот есть у тебя x.size(). Какого типа x? ICollection какой-нибудь, в котором этот size заявлен?

                                                А если ты этот size() реюзаешь в разных целях и общего интерфейса нету?
                                                Ответить
                                                • >А если ты этот size() реюзаешь в разных целях и общего интерфейса нету?


                                                  Тому я и сказал

                                                  >Алсо, нужна же наверное структутрная типизация?


                                                  Придется отказаться от понятия "класс", и просто скзаать "нечто с методом .size()"

                                                  А потом у тебя есть метод, который принимает нечто с мтеодом size() и методом petuh()
                                                  Ответить
                                                  • Ну в хаскеле таки пошли по более простому пути.

                                                    Сделали "интерфейсы" и запретили реюзать имена, по сути.
                                                    Ответить
                                                    • В "TS" типы тоже, в общем, не проверяются. Иначе сломался бы интероп с JS

                                                      Вот такое вполне работает
                                                      //
                                                      interface Cat {
                                                          nya(): void;
                                                      }
                                                      
                                                      // ничего не наследует и вообще даже не знает о Cat
                                                      class FortyYearsOldCPPHacker {
                                                          nya(): void {
                                                              console.log('NYA');
                                                          }
                                                      }
                                                      
                                                      function petTheCat(cat: Cat) {
                                                          cat.nya();
                                                      }
                                                      
                                                      petTheCat(new FortyYearsOldCPPHacker());

                                                      Утка-с
                                                      Ответить
                        • Petuh p(Petuh);
                          Petuh p();
                          "Нужно было просто делать синтаксис как в C++, и проблемы бы не было".

                          Кстати, из-за этого в реальных проектах встречались реальные факапы с лочками, когда вместо взятия лочки получалось объявление функции которое нихрена не делает.
                          Ответить
                          • ну борманд, ну уже 10 лет как завезли
                            Petuh p{}

                            именно для этого

                            Я ж спецом там не пустой ктор вызвал
                            Ответить
                            • > завезли

                              Да, теперь надо уметь читать вдвое больше кобенаций...
                              Ответить
                              • А зачем вообще вызывать
                                Petuh p()
                                ?

                                ты или не пиши скобочек, или пеередавай туда чото

                                или это могло как-то от шаблонов вылезти/
                                Ответить
                                • > зачем вообще вызывать

                                  Ну был у тебя конструктор с аргументом. Ты его порефакторил и аргумент убрал. Получи граблями по яйцам на ровном месте.
                                  Ответить
                                • Инициализировать все переменные явня — хороший тон. С "Petuh p{}" читающий будет уверен, что p реальня инициализирован, и что UB от его использования ня будет.
                                  Разумеется, p скорее всего* будет инициализирован и без скобочек, но чем меньше нядо вспоминать няканутых правил инициализации — тем лучше.

                                  *
                                  using Petuh = int;
                                  Petuh p;  // Сюрприз!
                                  Ответить
                                  • >Инициализировать все переменные явня — хороший тон

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

                                    Можно наверное наступить на такое

                                    Сам собой не инициализируется
                                    struct Foo {
                                     
                                    }


                                    А такой инициализруется небось
                                    struct Foo {
                                    public: Foo() {}
                                    }
                                    Ответить
                                    • > как это верно выразить в терминах современного стандарта?
                                      Объект с тривиальным конструктором по умолчанию (https://en.cppreference.com/w/cpp/language/default_constructor).

                                      > то он конечно сам собой не инициализируется
                                      Если Petuh — это класс, то он в любом случае инициализируется дефолтным конструктором. Просто если этот конструктор тривиален, то члены Petuh будут тоже инициализированы тривиальными конструкторами, и так до тех пор, пока ня встретится не-классовый (или как оно там) член, вроде int, который уже будет ня инициализирован.

                                      > Сам собой не инициализируется
                                      > А такой инициализруется небось
                                      Оба инициализируются одиняковым конструктором.

                                      А вообще вот: https://habr.com/ru/post/438492/ (Инициализация в С++ действительно безумна. Лучше начинать с Си). После прочтения этой статьи становится предельня понятня, почему лучше всё инициализировать явня.
                                      Ответить
                                      • блядь, вечно в этом путаюсь)

                                        В общем правильно считать так:

                                        Конструктор вызовется всегда и у всех членов, просто у членов "int" по умолчанию он НЕ устанавливает значение и потому не инициализирует

                                        Хотя на самом деле конечно никакого кода для вызова конструктора в объектный файл добавлено не будет для такого кода:
                                        struct Foo {
                                         int i;
                                        }
                                        Ответить
                                        • Примерня так, да. Поэтому я предпочитаю:
                                          struct Foo {
                                           int i = 0;  // Или int i{};
                                          }

                                          Теперь у Foo конструктор по умолчанию инициализирует i в 0.
                                          Ответить
                                          • Но ты же добавил ненужный код!

                                            А вдруг я хочу
                                            Foo f;
                                            ///
                                            ///
                                            if (koko) {
                                            f.i = 42;
                                            }

                                            я не хочу делать лишние действия))

                                            Спасибо за статью, но я дочитал до фразы "статическая продолжительность хранения", и переключился на английскую версию
                                            Ответить
                                            • > А вдруг я хочу
                                              Если у тебя Foo создаётся меньше миллиона раз в секунду — особой разницы ты ня увидишь. Нябольшая цена за избавление от головной боли.

                                              > переключился на английскую версию
                                              Да, она лучше.
                                              Ответить
                      • Здрасьте приехали. Обычная проблема областей видимости, либо импортируй класс с алиасом, либо используй префиксы, чтобы понять о чем речь. this.Pituh, Class::Pituh, package.Pituh
                        Не надо там никакого new. Это вот как раз странно, что компилятор дает тебе в одном скопе иметь два какие-то питуха, и различает их по new. Такой код и читать сложнее.
                        Ответить
                        • Ну так вот, либо ты обмазываешь конструкторы new, либо всё остальное this. В C# выбрали первое.
                          Ответить
                          • Ну такое.

                            В крестах я ведь могу написать Foo(x) как вызов конструктора и Foo(x) как функцию в текущем скопе. И ничего, как-то с этим живут.

                            Т.е. проблема есть даже если не писать new.
                            Ответить
                          • Выбрали ВСЁ обмазывать new, а достаточно было только конфликты имён (а это что блять, часто?) обмазать this.
                            Ответить
                            • Кмк жаберы выбрали "new" чтобы немного упростить понимание системы крестовичкам, чотбы крестовики понимали, что оно в куче создается (сомнительное решение)

                              Потом народилось новое поколение жаберов и шарпеев и джаваскриптеров с пыхерами, которые кресты отродясь не видывали, и для них "new" вот уж точно не имело никакого смысла.

                              Кстати, в ObjC у типа переменной, представляющей объект, указывается звездочка. Ну типа это же настоящий указатель(на объект в куче), и записывается как указатель. Звездочка там также не нужна по идее, как new
                              Ответить
                              • ObjC вроде бы сишку умеет, возможно там какие-то примитивы и без звезды работают.
                                Ответить
                                • Умеет. Причем в отличие от крестов он умеет ЛЮБУЮ сишку.

                                  но мне не оч понятно, почему нельзя было сделать это без зведочки. Строка и так не является валидным сишным кодом
                                  //
                                  NSGay * gay = [[NSGay alloc] init];
                                  Ответить
                                    • Вроде бы да, указатель на структуру "objc_object" в куче.

                                      Но не сырой. Иначе бы как работал референс каунтинг и вызов dealloc?:)
                                      Ответить
                                      • > референс каунтинг

                                        А он работал? 🙂

                                        Там же вроде вручную надо было дёргать retain и release на указателе. В общем-то на сишной структуре мне тоже никто не мешает это делать, если у неё внутри счётчик.
                                        Ответить
                                        • Ну когда-то не работал, и действительно нужно было retain и release вызывать, как у сома с AddRef

                                          Но уже лет семь как завезли ARC, который впиндюривает их.. хотя... он впиндюривает их уже после компиляции, чуть ли не на уровне LLVMного байткода..

                                          Так что ты прав: это может быть обычный указатель
                                          Ответить
                                          • что значит не работал? О_о

                                            он просто ручной был, но был же

                                            define "работал" тогда
                                            Ответить
                                            • > что значит не работал

                                              Ну я про ARC, его же не было изначально. Так что похоже, что это реально просто обычный сишный указатель на особую структуру. Без какой-то там магии.
                                              Ответить
                            • Как там решается описываемая эукариотом проблема?

                              А , у вас кодстайл другой: "method", но "Class"
                              Ответить
                              • А проблема ли это? Ну вот есть у меня глобальная функция и есть метод. Я думаю, что зову глобальную, а позвался метод. Чем это отличается от описанной ситуации?

                                Надо внимательней думать, что у тебя в локальном скопе. И не писать классы на тыщу строк.
                                Ответить
                                • Да я тоже не считаю это проблемой. В каком-то смысле это даже фича: в котлиновых либах есть такой хак, когда был вот

                                  foo = Petuh(123)

                                  а потом петуха сделали функцией, а не конструктором класса, и сохранили сырцовую совместимость

                                  В питоне тоже такое есть в джанге..

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

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

                                  Но видимо хотели быть похожими на кодстайл функций в винде
                                  Ответить
                                  • > В питоне

                                    В питоне нету, кстати. Там ведь методы без self не позвать.
                                    Ответить
                                    • методы -- нет, а свободные функции вполне.

                                      spam = Eggs()


                                      что мешает Eggs быть функцией?
                                      ------

                                      В реальной жизни так писать нельзя, конечно, но если ты пишешь крутую либу с кучей хаков и оптимизацией, то можешь себе такое позволить
                                      Ответить
                                        • >PEP8
                                          Верно. Потому в большинстве случаев проблемы нет в языках кроме C#, но в коде библиотек могут использовать такой хак для каких-то оптимизаций
                                          Ответить
                                          • > хак

                                            Ну что значит хак? Это ведь банальное кеширование чего-то в локалку. Можно и другое имя дать, чтобы читателю шаблоны не рвало.
                                            Ответить
                                            • Ну скорее всего кеширование, да.
                                              Хотя его бы лучше сделать через декоратор.

                                              К сожалению не вспомню сейчас где я это видел в джанге, но вот тебе пример из котлина

                                              //
                                                  val foo = BroadcastChannel<Int>(10)

                                              Думаешь, ``BroadcastChannel`` это класс?

                                              ///
                                              @ExperimentalCoroutinesApi
                                              public fun <E> BroadcastChannel(capacity: Int): BroadcastChannel<E> =
                                                  when (capacity) {
                                                      0 -> throw IllegalArgumentException("Unsupported 0 capacity for BroadcastChannel")
                                                      UNLIMITED -> throw IllegalArgumentException("Unsupported UNLIMITED capacity for BroadcastChannel")
                                                      CONFLATED -> ConflatedBroadcastChannel()
                                                      BUFFERED -> ArrayBroadcastChannel(CHANNEL_DEFAULT_CAPACITY)
                                                      else -> ArrayBroadcastChannel(capacity)
                                                  }


                                              Хотя под кодстайлу котлина разумеется функция не пишется с большой буквы
                                              Ответить
                                              • > не пишется с большой буквы

                                                Ну да. И опять же, тут просто фабричная функция, зачем её называть так же как и класс, который она создаёт? Ну напиши MakeBroadcastChannel или CreateBroadcastChannel.
                                                Ответить
                                                • >зачем
                                                  Ну потому что там был класс сначала, а потом его поменяли на фабричную функцию, чтобы вон сделать разные реализации.

                                                  Потому что ты не можешь вернуть разные реализации из конструктора же.

                                                  А хотелось НЕ заставлять клиентов менять код (хотя пересобрать его всё же придется -- скорее всего опкод там другой).

                                                  Я не защищаю этот подход, просто показываю, что он есть:)
                                                  Ответить
                                                  • > пересобрать его всё же придется

                                                    Тогда почему бы явно не сломать код клиентов, чтобы они не забыли пересобраться? Выглядит как какие-то грабли на ровном месте.

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

                                                      Я не думаю, что старая версия осталась.. Это был бы ад.

                                                      по идее вызов функции это invokestatic, а класс это "new" и "invokespecial".

                                                      А ты в крестах когда пишешь
                                                      do_all(petuh_krestux(42))

                                                      всегда понимаешь ``petuh_krestux`` это функция, или конструктор?
                                                      Ответить
                                                    • Потому что не хочется заставлять людей лишний раз править код, наверное.

                                                      Я не думаю, что старая версия осталась.. Это был бы ад.

                                                      по идее вызов функции это invokestatic, а класс это "new" и "invokespecial".

                                                      А ты в крестах когда пишешь
                                                      do_all(petuh_krestux(42))

                                                      всегда понимаешь ``petuh_krestux`` это функция, или конструктор?
                                                      Ответить
                                                      • > это функция, или конструктор

                                                        В основном да. Даже если всё в одном стиле, то по имени видно же обычно... Если существительное -- значит конструктор, если глагол -- значит функция.
                                                        Ответить
                                                          • > какой size() ))

                                                            Угу, в крестах одно время ещё был дурацкий приём, когда геттер и сеттер для свойств делали с одним именем. Что-то в духе:
                                                            int size();
                                                            void size(int);
                                                            Ответить
                                                            • Какой ``std::stringstream::str`` ))

                                                              Почему не делать как в жобе: с префиксом "get" и "set"?

                                                              Или почему не сделать проперти как в C# и котлине?
                                                              Ответить
                                  • Он даже SRP отвечает: "реализует программу" и больше ничего.
                                    Ответить
                                  • Он даже SRP отвечает: "реализует программу" и больше ничего.
                                    Ответить
                                    • А когда я хочу написать новую программу, я просто наследую её от старой, чтобы переиспользовать полезный функционал
                                      Ответить
                                • > Ну вот есть у меня глобальная функция и есть метод. Я думаю, что зову глобальную, а позвался метод.
                                  В сисярпе такое невозможно, там никаких глобальных функций нет. В качестве "глобальных функций" можно использовать статик класс со статик методами, но они вызываются как ClassName.MethodName, так что никакой проблемы нет.
                                  Ответить
                                  • А нелья заимпортировать через using "MethodName", чтобы не писать каждый раз имя класса?

                                    хуйню написал, у вас же там не классы импорятстя, а неймспейсы, да?
                                    Ответить
                                    • > у вас же там не классы импорятстя, а неймспейсы, да?
                                      Да. Но для класса можно сделать алиас
                                      using Cock = MyApp.Petushok;

                                      и теперь вместо Petushok.MethodName можно использовать Cock.MethodName.
                                      Ответить
                                      • А для метода нельзя?

                                        Вообще заметил, что C# больше похож на C++ в этой области: тоже неймспейсы с классами, тоже алиасы для классов.
                                        Аналогов джавьих пакетов нет
                                        Ответить
                                        • > А для метода нельзя?
                                          Нельзя.
                                          > C# больше похож на C++ в этой области
                                          Ну, Хейлсберг сам говорил, что C# — это не клон Java и ближе к C++ (хотя по факту конечно напизжено из жабы очень много). В unsafe можно вообще точно так же пойнтеры использовать как в C/C++.
                                          Ответить
                                      • А что ты кстати пишешь на .net? Десктоп или веб? Под винду? Какие фреймворки сейчас в моде?
                                        Ответить
                                        • Веб бэкэнд, ASP.NET Core 5, пишу на шиндовс, продакшен на линуксе.
                                          Ответить
                  • ну введи в гуглтранзлейт "press any key to continue", и нажми на значок динамика
                    Ответить
                      • Саныч, зря смеешся. Эникейщики работают через день на 600-700 баксов, ни за что, в отличие от программера не отвечая. Мало, но одному прожить в Москве можно (если есть где жить, конечно). Даже на буббльгум деньги останутся. Вот B.C.Луговский работал эникейщиком в ОНТИЛ ИФВЭ, Хаскель в свободное время изучал.:)

                        https://www.linux.org.ru/forum/talks/913456?cid=913826
                        Ответить
                • Цитаты великих людей:

                  хороший язык
                  люблю CLR и люблю функциональщину

                  но у меня на клавиатуре нету ψ, и потому мне он не подойдет
                  придется делать стартап на пхп


                  /19653#comment316725

                  мне кажется, это ранний МАКАКА
                  Ответить
            • Абзацный отступ, кстати, это indent, а dedent это типа анти отступ. Типа как в decrypt, только dedent
              Ответить
        • в коко тоже такое есть: тройные ковычки могут быть многочтрочными, и у них есть метод trim() потом, чтобы удалить отсуттпы
          Ответить
          • Трим отрежет табы внутри строки после перевода каретки?
            Ответить
            • Я забыл уже, какой язык на этой неделе я считаю языком богов, но скорее всего там хередок.
              Ответить
                • а, понял тебя.

                  Из Euphoria formal syntax:
                  RAWSTRINGLIT ==: DQRAWSTRING | BQRAWSTRING
                  DQRAWSTRING ==: '"""' [ MARGINSTR ] [CHAR ...] '"""'
                  BQRAWSTRING ==: '`' [ MARGINSTR ] [CHAR ...] '`'
                  .

                  соответственно, можно так

                  sequence q = """ 
                  No, really
                  I do like Euphoria
                  """ 
                  puts(1,q)
                  Ответить
                  • блядь, ни одной вакансии на hh.ru со словом "Euphoria" вообще!

                    vb.net есть, а эйфории нет
                    Ответить
                    • because your C/C++ package has 57 different routines for memory allocation, and 67 different routines for manipulating strings and blocks of memory. How many of these routines does Euphoria need? Answer: zero. In Euphoria, memory allocation happens automatically and strings are manipulated just like any other sequences.
                      -------
                      к сожалению, это всё написано про C++98
                      Ответить
                      • because you hate it when your program starts working just because you added a debug print statement or compiled with the debug option


                        какой багор ))
                        Ответить
                        • > you added a debug print statement

                          Забыли написать, что где-то в совершенно левом месте, которое не имеет отношения к точке, где реально таится бага.
                          Ответить
                          • У меня в джаве как-то были гонки, и при дебаг принте не воспроизводились
                            Ответить
                            • Да это и с железом бывает. Подключаешь осциллограф и глюки проходят.

                              Наблюдать, не влияя на эксперимент, сложно.
                              Ответить
                              • Эффект наблюдателя же:)

                                А еще бывает генеральский эффект, или эффект админа: комп у бухгалтерши глючит. Админ приходит -- комп не глючит. Уходит -- снова глючит
                                Ответить
                    • прикольнись, запости первую

                      "требуется программист на Euphoria для поддержки высоконагруженного сервиса aka социальная сеть для общения программистов"
                      Ответить
      • в шеле
        $ mail tatiana << END
        > Я вам пишу
        > чего же боле
        > END


        Точно так же можно и с переменныи
        Ответить
          • END в начале означает: "Далее следует кусок текста, завершающийся словом END"

            Можно любое слово на месте его использовать
            Ответить
          • потому что это название маркера, который может быть любым

            прямо как в php /green
            Ответить
            • Реально как в «РНР»:

              $str = <<<EOT
              Пример строки,
              охватывающей несколько строк,
              с использованием heredoc-синтаксиса.
              Здесь не нужно экранировать ни одинарные ', ни двойные " кавычки.
              EOT;
              print_r($str);
              Ответить
        • В «до-диезе»:
          string str = @"
          Multiline
          string.
          ";

          Можно с интерполяцией
          int var1 = 1;
          int var2 = 2;
          var str = $@"
          var1={var1}
          var2={var2}
          ";
          Ответить
    • if (line.length() > MaximumLineLengthOf80Characters)
      throw new
      TooLongLineExceedingRecommendedMaximumLe ngthOfEightyCharactersForCompatibilityWi thOldPrintersEncounteredException
      ();
      Ответить
      • (хотя, конечно, правило полезное, а то понапишут строчек, потом приходится шрифт мелкий делать и глаза об него ломать.)
        Ответить
  • В PHP он тоже есть. Имейте это в виду, когда задумаетесь, на какой бы язык перейти.
    Ответить
  • Ротоёб написал статью на медиум.

    Наслаждаемся:

    Java убьет ваш стартап. PHP спасёт его.
    https://medium.com/nuances-of-programming/java-unichtozit-vash-startap-7c07c5f1ca75

    PHP-программистов больше и они дешевле чем Java-программисты.

    У PHP отличная производительность и становится она только лучше. На деле, он с легко конкурирует с компилируемыми языками.


    PHP не «скриптовый» язык (что бы это ни значило), это мощный, полнофункциональный, объектно-ориентированный язык.


    PHP создан для веб. Никаких дополнительных серверов, процессоров, хаков, уловок не нужно. Он буквально един с вашим сервером.
    Ответить
    • Если чувак не умеет программировать, а могёт только придумывать стартап, то ему только в «РНР» и дорога. Какие, однако, пидорасы эти писатели статей!
      Ответить
      • PHP-программистов больше и они дешевле чем Java-программисты.
        Ответить
      • ``mod_php`` же, и правда:)

        А может они о том, что сделали в ВК? Там вроде весь код линкуется в итоге в один бинарь с HTTP сервером
        Ответить
      • вы под влиянием невозбранно спиздившего код у мейлсру Сысопова совсем уже почти докатились до цє GI
        Ответить
        • Каким образом сысоев мог что-то спиздить у мейлру?
          Там наверняка апаче был. Вообще в 2000-м году ничего не могло быть кроме апаче ни на каком юниксе (были еще сервера от лотуса и сана, но в дикой природе они не встречались)
          Ответить
          • не мог, но всё равно спиздил продвигает Сысопова сразу в пацаны
            Ответить
      • ...... обмазываюсь ПХП и представляю что я единый организм апач.....
        Ответить
    • круто, а сервер с воздуха появится? А дыру в безопасности из-за открытого всем ветрам сервака боженька залает? Или придется потратиться еще и на целый отдел безопасности?

      Во-первых чужие хостинги часто говно для своего софта на пыхапы - потому что жадные хостеры экономят на всем и простой поиск в базе будет занимать минуты.

      А свой хостер поднять не имея никаких знаний по безопасности - это дыра безопасности. Ведь как обычно предлагают в учебниках по настройке апатча? "Ну если у вас что-то не работает, отключите все антивирусы, брандауэры"... Обычно так и оставляют, ведь знания как сделать чтобы работало без отключения не появилось, а работать оно как обычно должно еще вчера.


      p.s. Лучший язык для стартапа - JavaScript через Node.js
      Ответить
      • > Ведь как обычно предлагают в учебниках по настройке апатча?

        Приведите реальный пример такого учебника.
        Ответить
      • >p.s. Лучший язык для стартапа - JavaScript через Node.js
        Это зависит ))

        Плюс JS в том, что можно писать и фронт и бек. Но если твой стартап это не веб прилоожение с SPA, то я не уверен в выборе языка

        Ну и лучше сразу взять TS, как только чуть чуть выучишь JS
        Ответить
  • Лучшие языки программирования для стартапов

    1. PHP
    Серверный язык сценариев PHP широко используется как молодыми, так и опытными компаниями. Хотя есть много способов применить PHP, он часто используется для создания динамических веб-приложений. Дополнительные качества, которые делают его хорошим выбором для стартапов, - это его высокая производительность и открытый исходный код. Благодаря простоте использования он также может ускорить вывод продукта на рынок.

    https://itanddigital.ru/itstartup
    Ответить
  • Mac это другая система, другая архитектура, другая идеология... Винда была хороша когда была XP, может быть ещё 7 была хороша... Остальное - работать не реально, нужную настройку не найти, тачпад? Увы, но как бы я не любил Винду на маках тачпад охренителен, я такого больше ни на одном буке не встречал.... Когда я переслал с Винды на мак, мне жутко не хватало софта, особенно для работы с ssh, sftp..Кто попробовал однажды XManager вряд-ли от него сможет отказаться.....Увы,но на мак аналог я искал очень долго.... Royal TS спас положение. Про хоткеи - у 16 мака же тачбар... Выведите туда что нужно. На клавиатуре всегда тоже можно настроить хоткеи, да долго, но практически все современные редакторы/блокноты поддерживают переносимый профиль (sublime, vscode...). Если уж совсем тяжко - virtualbox + ubuntu ). Вообщем - по винде есть небольшая ломка,но только до тех пор пока нет необходимости что-то настраивать....
    Ответить
    • >>Когда я переслал с Винды на мак, мне жутко не хватало софта, особенно для работы с ssh, sftp
      Он ебанутый чтоли?

      ssh там из коробки.

      Мак это микроядро Mach + верхний слой из FreeBSD = ядро XNU
      Поверх юзерленд спиженный из FreeBSD = DarwinBSD
      --дальше пошла проприетарщина--
      Поверх CoreFoundation
      Поверх Cocoa, AppKit, Quartz и что там еще == OS X

      Так что внунтри мака нормальный ssh, как во FreeBSD

      Пиздец, чувак нихуя ни в чем не понимает, а уже статью писать
      Ответить
        • Хм, открыл cmd, ввожу ssh
          usage: ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface]
          [-b bind_address] [-c cipher_spec] [-D [bind_address:]port]
          [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11]
          [-i identity_file] [-J [user@]host[:port]] [-L address]
          [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
          [-Q query_option] [-R address] [-S ctl_path] [-W host:port]
          [-w local_tun[:remote_tun]] destination [command]

          Оказывается, его завезли ещё в 1809.
          Ответить
              • ну просто обычный openssh же умеет тока в терминале работать, а чтоб запустить его поверх cmd нужно эмулить XTERM поверх ConsoleAPI винды, вот мне интересно как это сделали
                Ответить
  • Ребят, спасибо вам всем большое за минусы (тем кто поддерживает конечно же огромное уважение).
    Конечно же эта заметка возможно совсем не для хабра + я попутал с хабами и не мог определиться, Спасибо todoman, что подсказал про Чулан.
    Я относительно недавно начал находить свободное время и силы, так как перестал работать дома и теперь вижу, что смысла мне пробоваться как автору на Хабре нет. Да и было просто желание чем-то поделиться, видать не тем чем нужно ))))
    Теперь я понимаю, что лучше тратить время на что-то другое.
    Это все написано на самом деле с чувством благодарности! Спасибо вам!
    Ответить
  • Ребят, спасибо вам всем большое за минусы (тем кто поддерживает конечно же огромное уважение).
    Конечно же эта заметка возможно совсем не для хабра + я попутал с хабами и не мог определиться, Спасибо todoman, что подсказал про Чулан.
    Я относительно недавно начал находить свободное время и силы, так как перестал работать дома и теперь вижу, что смысла мне пробоваться как автору на Хабре нет. Да и было просто желание чем-то поделиться, видать не тем чем нужно ))))
    Теперь я понимаю, что лучше тратить время на что-то другое.
    Это все написано на самом деле с чувством благодарности! Спасибо вам!
    Ответить
    • Ещё прикольно получилось: 12:42 пришло сообщение на почту: вам доступен значек "Захабренный", в 1:55 - вам доступен значек "Отхабренный". Полет был не долгий))))
      Ответить
        • Спасбо, уже няшла.

          > Хотя что там интересного?
          Как что? Ещё больше тупых комментариев, конячно <( ̄︶ ̄)> !
          Ответить
        • Какая-то бессмысленная хуита

          Скоро на хабре будут такие статьи:

          Вчера я прибухнул с друзьями, башка с утра немного трещала, но я посрал, выпил рассолу огуречного, и стало ничего

          Спасибо за внимание
          Ответить
          • Познакомившись впервые с языком Котлин после продолжительной работы с Java меня воротило от одной мысли, что null-safety может быть полезен...

            В общем шло время, потихоньку начинал привыкать к тому, что null может не существовать, даже пытался сделать что-то на мой тот взгляд идиоматичное: дефолтные значения в виде объекта.... В общем все это меня вгоняло в тоску и я очень хотел опять писать на Java, так как привык жить с null. Прошло время я уже нормально начал жить с котлиновским not nullable, и стало ничего

            Спасибо за внимание
            Ответить
          • регулярное сидение на Хабре явно разжижает мозги

            вон взять Романа: на ГК Стандарт от его зубов отскакивал, а на Хабре он про тугосерь исполнял
            Ответить
        • > я был свободным человеком
          > я спокойно сидела на fedora

          Вот до чего мак доводит.
          Ответить
      • Ребят, спасибо вам всем большое за минусы (тем кто поддерживает конечно же огромное уважение).
        Ответить
    • У автора все статьи помоечные.
      Вот например автор открыл для себя нулл сейфети, и пытается сам себе объяснить зачем оно нужно
      https://habr.com/ru/post/560634/
      Ответить
      • Там в комментах пишут, что в Коко «null safety» достигается за счёт дополнительных проверок в рантайме. Это реально так? Это же пижьец!
        Ответить
        • А как без них? Ты можешь за счёт типизации держать null safety в какой-то области. Но на входе в неё проверка неизбежна. Не объявлять же это UB'ом.
          Ответить
          • А в чем тогда вообще фишка? В крестах, если у нуллу обратился, то программа упадёт. И никаких проверок в рантайме попрошу заметить!
            Ответить
            • Чтобы не жить в страхе, что в каждой переменной может быть нулл... Ну и чтобы явно подсветить для читателя те редкие кейсы, где нулл нужно обработать потому что там что-то опциональное.
              Ответить
              • > Чтобы не жить в страхе

                Программисты живут в постоянном страхе, ведь в переменной может оказаться печально известный нулл и программа упадёт (как в Коко).

                > Ну и чтобы явно подсветить для читателя те редкие кейсы, где нулл нужно обработать потому что там что-то опциональное.

                Это кривая реализация optional или абстракция протекла?
                Ответить
                • > Это кривая реализация optional

                  Как-то так, да. По-хорошему всё должно быть нот-нулл. Кроме тех мест, где optional/nullable. Но это язык с нуля дизайнить надо, а не на основе джавы.
                  Ответить
                  • В общем концепция была бы хороша, если бы все проверки проходили на этапе компиляции и нулл вообще отсутствовал как явление. Ну и опционал был бы хороший. А так это больше похоже на костыль, который и к без того медленной йаже добавляет бесчисленное множество проверок на нулл.
                    Ответить
                    • Ну вот в крестах, кстати, есть гарантия, что в ссылках не может быть нулла (в отличие от указателей).

                      А если ты её туда сам засунул -- ССЗБ.
                      Ответить
                      • В крестах можно и вовсе без ссылок обойтись, если объекты мелкие или легкоподвижные

                        В джавке этого нехватает, кончно
                        Ответить
                        • Ну там jit умеет оптимизировать ситуации, когда ссылка за область анализа не убегает. Так что какие-то простые примеры он оптимизнёт и уберёт new.

                          Тут вопрос в том, надо ли усложнять язык новыми концепциями, если более-менее получается и без них.
                          Ответить
            • > В крестах, если у нуллу обратился, то программа упадёт.
              Если повезёт.
              struct foo
              { 
                  int a;
                  void bar() { std::cout <bar();

              Этот код скорее всего не упадёт.
              Загадка: если предыдущий код гарантированно не упадёт, может ли упасть этот код:
              x->bar();
              if (x)
                  x->a = 0;
              Ответить
                • Ну да, это классический пример оптимизации и анализа кода: если указатель разыменовывают, то он не нулл, программист же не идиот и не напишет UB, значит следующая проверка на нулл — не нужна. Мы оптимизировали сравнение и ветвление.
                  Ответить
              • > может ли упасть этот код

                Вот так и появляются уязвимости...
                Ответить
              • А ещё есть платформы, где в нулл можно писать. Просто какая-нибудь таблица прерываний помнётся и код когда-нибудь потом крашнется.
                Ответить
                  • Но ведь с точки зрения стандарта это сделать нельзя и вообще UB?

                    Ибо адрес функции не получен при помощи взятия адреса функции.

                    З.Ы. Срачи про няшную и позиксовый dlsym по-моему до сих пор продолжаются...
                    Ответить
                    • В embedded обычно на стандарт смотрят не очень пристально. А начать исполнения кода с нулевого адреса при инициализации вполне какая-то железка может.
                      Ответить
                      • > на стандарт смотрят не очень пристально

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

                        На ARM'е, к примеру, в младшем бите указателя на код лежит индикатор arm/thumb.
                        Ответить
                  • Тут вроде бы обсуждали, что nullptr не обязан быть нолем?)

                    Писать нельзя в nullptr же
                    Ответить
                    • Но после int* x = 0; и int* y = nullptr; x == y. Так что, какое конкретно представление у nullptr неважно, ты его всё равно не увидишь.
                      Ответить
                    • Но после int* x = 0; и int* y = nullptr; x == y. Так что, какое конкретно представление у nullptr неважно, ты его всё равно не увидишь.
                      Ответить
                      • Это потому что для совместимости с сишкой "0" в этом контексте экивалентен nullptr. А вот если няписать "int* x = 1 - 1; int* y = nullptr;", то x == y Стандартом ня гарантируется.
                        Ответить
        • null safety проверяется и в компайл тайме, и в рантайме.
          JVM это не то место, где нужно экономить на сравнении указателя с нулом. Если это вот прямо хотспот, то его джит джитнет.
          Ответить
        • null safety проверяется и в компайл тайме, и в рантайме.
          JVM это не то место, где нужно экономить на сравнении указателя с нулом. Если это вот прямо хотспот, то его джит джитнет.
          Ответить
    • При чем тут хехедок? Или оффтопь в другое место, здесь для хередока тред.
      Ответить

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

Помни, guest, за тобой могут следить!

    А не использовать ли нам bbcode?


    8