Рефлексия в Си или вызов функции по имени в переменной

JonHappy1
Offline
Зарегистрирован: 11.06.2018

sadman41 пишет:

Не знаю ни одной нормальной либы, которая бы тащила за собой стринги. И String не только по пече... progspace бъет, он еще мозги выносит знатно на отладке и эксллуатации.

WebSocketClient.h

sadman41
Offline
Зарегистрирован: 19.10.2016

Я же про нормальные писал...

JonHappy1
Offline
Зарегистрирован: 11.06.2018

пока я вижу проблему только с доп размером. рзбираться с отладкой дело привычное , тут хоть в Serial можно инфу вывести, я в своё время с кристаллом 1806 помучился и 51 однокристалкой - дак там только осциллограф как индикатор работы  и то не цифровой .
 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

JonHappy1 пишет:
добавление String (в той или иной форме) добавляет 1 кб к коду, т.е. саму либу по работе со строками.

Это точно! А во время выполнения она динамически хапает RAM, которого всего 2 кило, до тех пор, пока стэк её данные не пропорет. А когда пропоет, Вы придёте сюда и будете требовать ответв на простоя вопрос: "какой дурак этот стринг туда засунул"

JonHappy1 пишет:
очень мало вероятно, что String ни одна другая либа не использует

Я не знаю, кто такая либа, но если Вы имеете в виду библиотеку, то системные (поставляемые с системой) - ни одна не использует (разве что в перегруженных параметрах, так их можно (и нужно) не пользовать). А какие-то другие (third party), тут да - нам неоткуда знать какие субстанции и с каких помоек Вы собираетесь в свой код пихать.

JonHappy1 пишет:
мой вариант короче по коду и намного наглядее. и следовательно имеет право на существование.

Право на существование имеет даже отрицание самого феномена существования, а Ваш код тем более. А как Ваш код будет работать - дело Ваше, дерзайте.

 

JonHappy1
Offline
Зарегистрирован: 11.06.2018

вот без String, но по имени


typedef void (*FunctionPointer) (void);


void xxx01()
{
  Serial.println("xxx01");
}
void xxx33()
{
  Serial.println("xxx33");
}
typedef struct STR {
  char x[5];
};

const  FunctionPointer numeral[] = {xxx01, xxx33};
STR  str[] = {"xxx01", "xxx33"};

void setup() {
  Serial.begin(9600);
  char cc[] = "xxx33";


  int  i = sizeof(str) / sizeof(str[0]);
  for (int j = 0; j < i; j++) {
    if (! strcmp(str[j].x , cc)) {
      numeral[j]();
      break;
    };
  }
}

void loop() {
}





 

sadman41
Offline
Зарегистрирован: 19.10.2016

А это вообще законно: char cc[2] = "xxx33" ?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sadman41 пишет:

А это вообще законно: char cc[2] = "xxx33" ?

Ну, а почему нет? Работать будет. Другой вопрос, что будет делать? Боюсь, не то, чего автор ожидал :)))

JonHappy1
Offline
Зарегистрирован: 11.06.2018

sadman41 пишет:

А это вообще законно: char cc[2] = "xxx33" ?

это "опечатка" и не только эта, исправил

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Интересно, как именно исправил :)

JonHappy1
Offline
Зарегистрирован: 11.06.2018

 

char cc[] = "xxx33";

 

и тут

typedef struct STR {
char x[5]
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ну, если так, то моя ремарка отсаётся в силе:

ЕвгенийП пишет:
Работать будет. Другой вопрос, что будет делать? Боюсь, не то, чего автор ожидал :)))

JonHappy1
Offline
Зарегистрирован: 11.06.2018

как решит компилятор - либо обрежит , либо изменит размер

но не работало...

Logik
Offline
Зарегистрирован: 05.08.2014

JonHappy1 пишет:

2Logik
вариант правильный с тчки зрения исполняемого кода, но с точки зрения написания кода....
надо учесть , что пишется система и в ней много разных аспектов
что ечть сейчас и как работает
есть портал написан на java, работает и под окнами и под линуксами,
там N страниц, на каждой странице до 30 вызовов ws на сервер для обработки данных ,
вотправляем сообщение xxx44|data - на сервере (для каждой страницы есть файл jsp,  который обрабатывает команды с этой страницы, но точка входа для всех сообщений с клиентов одна, она и вызывает нужную команду(метод) с передачей данных)  метод с именм xxx44 обрабатывает данные и (если надо) отправляет результат  такого же формата xxx44|newdata
браузер "рефлексией" javascript выполняет функцию xxx44 с данными newdata. все наглядно . прозрачно.

также я хочу и тут, да это будет несколко затратно, но зато я знаю что вызов на сервере приведёт к выполнению нужной мне функции. да я могу по номеру , отправленному с сервера, вызвать функцию. но для этого мне надо на сервере ещё и таблицу соответствия хранить, а если что-то удалилось/добавилось надо ещё и эту таблицу менять (это можно автоматизироватьЮ конечно) но это гемор, если я счас отпправляю простое текстовое сообщение, то тут нужно будет обращаться к таблице...

чем не устраивает мой вариант? http://arduino.ru/forum/programmirovanie/refleksiya-v-si-ili-vyzov-funkt...
 

Конкретно о недостатках того варианта. 1. String - уже писали, свежый вариант без стринга видел. 2. numeral[4] и String st в коде никак не связаны,  а по логике между ними есть связь, причем очень жесткая, отношение один - один. Его легко нарушить и это будет очень непросто обнаружить даже при десятке функций, а при сотне вобще мрак. Варианты от форумчан со структурой лишены такого. 3. Таблица с именами функций, от которой стараетесь избавится на сервере - она всеравно есть по факту в String st, причем существует в таком количестве экземпляров сколько клиентов ардуин в системе. Очевидно это сильно более чем 1 экземпляр на сервере и  обеспечение синхронных изменений таблиц на всех клиентах - очень геморная задача. 4. Отсутствие контроля имен на сервере дает принципиальную возможность поступления на ардуину неизвестной функции. Показаный код при этом рухнет (st.indexOf(cc) не наншло имени и...). При этом сервер даже не узнает что случилось. Это поправимо в принципе. 5. Ограничение на формат названия функций. Вместо осмысленных названий произвольной длинны во всей системе приходится довольствоватся только "xxx44". Удобства в этом нет.

ПС. Приймите как данность - преобразование имени в ID избежать не выйдет принципиально, у вас в коде это st.indexOf(cc)/5.Из всех вариантов преобразования самый адекватный через таблицы с именами функций и вопрос только один. ГДЕ? На сервере у которого много памяти, производительности и одна таблица на всю систему или на ардуинах у которых ресурса кот наплакал и куча таблиц разной степени старости.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

JonHappy1 пишет:

как решит компилятор - либо обрежит , либо изменит размер

Не то и не другое. Расположит поверх других данных. Опишите что-нибудь после этого, узнаете много интересного.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

3. Таблица с именами функций, от которой стараетесь избавится на сервере - она всеравно есть по факту в String st, причем существует в таком количестве экземпляров сколько клиентов ардуин в системе.

таких таблиц нет, это нет, хотя бы потому , что такого термина в java нет. есть
public static HashMap<String, Object> ListCommand;
он заполняется при запуске серверного приложения. он служит для того чтоб в одном месте хранить "пути" к методам , которые находятся в разных файлах.

4. Отсутствие контроля имен на сервере дает принципиальную возможность поступления на ардуину неизвестной функции

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

Показаный код при этом рухнет (st.indexOf(cc) не наншло имени и...). При этом сервер даже не узнает что случилось

таких проблем за много проектов ни разу не было

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

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

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

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

JonHappy1
Offline
Зарегистрирован: 11.06.2018

ЕвгенийП пишет:

JonHappy1 пишет:

как решит компилятор - либо обрежит , либо изменит размер

Не то и не другое. Расположит поверх других данных. Опишите что-нибудь после этого, узнаете много интересного.

как-то не приходилось

Logik
Offline
Зарегистрирован: 05.08.2014

JonHappy1 пишет:

таких таблиц нет, это нет, хотя бы потому , что такого термина в java нет. 

Этот термин люди в школе учат. Например на математике так и говорят. И от того куда Вы её засуните: в лист, массив, список, БД или стринг, как в примере, суть не меняется. Если она уже есть - на сервере, так и пользуйтесь ею и не плодите сущности.

JonHappy1 пишет:

..как правили ... и обработчик ардуинки должен иметь такое же имя 

Должен - не обязан, а правила имеют исключение. Ввведение новой функции потребует доработки и перепрошивки всех клиентов, иначе прийдет на них это неизвестное 

JonHappy1 пишет:

Показаный код при этом рухнет (st.indexOf(cc) не наншло имени и...). При этом сервер даже не узнает что случилось

таких проблем за много проектов ни разу не было

 

Я ж четко написал "сервер даже не узнает что случилось"

JonHappy1 пишет:

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

вот с этим буду спорить...

Тут у Вас полный бред. Коментировать не буду, любому очевидно о чем "SendWebSocketMsg" и никто не поймет ххх43. 

JonHappy1 пишет:

эту таблицу придется заполнять ручками

 

А код вобще ими пишут. И очевидно проще таблицу менять в одной точке на сервере, ручками, чем перепрошить сетку ардуин. Причем не удаленно, а добравшись до каждой, ручками, где бы она не засунута, открутив ручками  и подключив тоже ручками.

ПС. Забудте вы о джавах. Для МК свои подходы и опыт джавы только мешает.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

Цитата:
Если она уже есть - на сервере, так и пользуйтесь ею и не плодите сущности.
ну не надо не зная всего, советовать , что использовать, в этоn HashMap никаким местом не встанет указатель на ардуинки

Цитата:
Должен - не обязан, а правила имеют исключение. Ввведение новой функции потребует доработки и перепрошивки всех клиентов, иначе прийдет на них это неизвестное
конечно не обязян, но только надо сделать так , что глядя на текст а ардуинке понять что искать в серверной части сразу, а не лесть сначала в какую-то таблицу и только потом искать в коде.

Цитата:
Я ж четко написал "сервер даже не узнает что случилось"
для этого существует обратная связь по ws которая сообщит серверу.

Цитата:
Тут у Вас полный бред. Коментировать не буду, любому очевидно о чем "SendWebSocketMsg" и никто не поймет ххх43.
ты привел одно название  а тперь придумай их 3-4 сотни. и получается что навание будет охиренной длины. этот путь уже пройден. необходимости в длинных названиях нет.

Цитата:
А код вобще ими пишут. И очевидно проще таблицу менять в одной точке на сервере, ручками, чем перепрошить сетку ардуин. Причем не удаленно, а добравшись до каждой, ручками, где бы она не засунута, открутив ручками  и подключив тоже ручками.
мой список методов HashMap ручками ни кто не заполняет, я добавил/удалил/изменил метод в java и мне этого достаточно, приложение само найдет где располоены методы и запонит этот HashMap. если клиент вызовет не существующий метод - будет исключение - в логах все пропишется. если сервер отправит клиенту вызов не существующей функции - так же увижу исключение. не кто не мешет и в ардуинке сделать такое - отправить сообщение серверу если тут
 

for (int j = 0; j < i; j++) {
    if (! strcmp(str[j].x1 , cc)) {
      numeral[j]();
      break;
    };

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

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

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

JonHappy1 пишет:

но для этого мне надо на сервере ещё и таблицу соответствия хранить,

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

Цитата:

а если что-то удалилось/добавилось надо ещё и эту таблицу менять

Зачем менять?

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

Надобность в изменении может наступить только тогда, когда Вы зальете в Ардуину новую прошивку - с другим набором функций.

 

В общем, Вам нужно понять (или хотя бы запомнить) одну простую мысль: если между Ардуиной и сервером следует как-то разделить работу, то ее следует разделять, исходя из единственного принципа: все, что может делать сервер, должен делать сервер, а Ардуина - только то, что сервер сделатьв принципе не в состоянии (например, прочитать показания с аналогового датчика или состояние аппаратной кнопки).

В Вашем конкретном случае трансляция текстовых имен в коды должна присходить на стороне сервера.

sadman41
Offline
Зарегистрирован: 19.10.2016

В ардуинах строковые функции еще принято в PROGMEM совать, а это отдельная песня. Кстати, если я правильно понимаю, то любой вновьведенный на сервере ID вызова требует модификации клиентской части, разве нет? Ведь то, что предполагается вызывать по имени, необходимо прежде всунуть в МК. Но лично я за короткие пакеты, если они не обязаны быть человекопонятными (не вводятся руками, как в шелле, к примеру) - и ресурса меньше тратится и парсинг проще.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

JonHappy1 пишет:

Показаный код при этом рухнет (st.indexOf(cc) не наншло имени и...). При этом сервер даже не узнает что случилось

таких проблем за много проектов ни разу не было

Ну, то есть Вы об этих проблемах так и не узнали.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

Цитата:
От того, что Вы что-то удалите/добавите на сервере, количество и состав функций, поддерживаемых Ардуиной, не изменится. Следовательно, менять ничего не нужно.
но в процессе разработки там накопится такое количество, что трудно понять что нужно, а что нет.

Цитата:
В общем, Вам нужно понять (или хотя бы запомнить) одну простую мысль: если между Ардуиной и сервером следует как-то разделить работу, то ее следует разделять, исходя из единственного принципа: все, что может делать сервер, должен делать сервер, а Ардуина - только то, что сервер сделатьв принципе не в состоянии (например, прочитать показания с аналогового датчика или состояние аппаратной кнопки).
это пока одна ардуинка, а если их больше десятка?  то что к чему относится ? зашел в код ардуинки и что искать в коде сервера? я моём варианте я могу на каждую ардуинку назначить свой префикс aaaa dddd

и к тому мой последний варант отличается от предложенного с номерами сотней байт.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

andriano пишет:

JonHappy1 пишет:

Показаный код при этом рухнет (st.indexOf(cc) не наншло имени и...). При этом сервер даже не узнает что случилось

таких проблем за много проектов ни разу не было

Ну, то есть Вы об этих проблемах так и не узнали.

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

JonHappy1
Offline
Зарегистрирован: 11.06.2018

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

Цитата:
Ведь то, что предполагается вызывать по имени, необходимо прежде всунуть в МК. Но лично я за короткие пакеты, если они не обязаны быть человекопонятными (не вводятся руками, как в шелле, к примеру) - и ресурса меньше тратится и парсинг проще.
и это тоже к коротким именам фунций. можно вообще  называт x02 (к примеру) но такое имя трудно найти в тексе xxx02 быстрее найдётся взглядом. да такое удобство в ардуинке стоит дороже. но смысловое длинное название я вно слишком дорого.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

вот ардуино отправляет

void loop() {
  detachInterrupt(1);
  wsclient.monitor();
  a = sensor.readRangeSingleMillimeters();
  mdist[(i++) & 0x07] = a > 1200 ? 1200 : a;
//фильтрация
  dist = (mdist[0] + mdist[1] + mdist[2] + mdist[3] + mdist[4] + mdist[5] + mdist[6] + mdist[7]) / 8;

  uint8_t d[] = "xxx03|    ";
  j = 9;
  while (dist > 0) {
    d[j--] = uint8_t ((0x30 + dist % 10));
    dist /= 10;
  }

  wsclient.send((uint8_t*)(&d), sizeof(d));
  attachInterrupt(1, EventListener, FALLING    );
  //  delay(50);
}

вот метод java обрабатывающий ответ от ардуино

public void xxx03(String param, Session userSession) {

        m[x] = 940 - Integer.parseInt(param.trim());

        d = (d < 511) ? x : 512;
        v = d < 512 ? 0 : x;
        sb.append("xxx03|<polyline stroke='red' stroke-width='1px' fill='none' points=' ");
        for (int z = 1; z < d; z++) {
            sb.append(z).append(",").append(m[(z + v) & 0x01ff]).append(" ");
        }
        sb.append("' />");
        SendMessage("admin", sb.toString());

        sb.delete(0, sb.length());
        x = (x + 1) & 0x01ff;

    }

вот код рисующий график (при добавлении новой тчки происходит сдвиг в лево)

            var sv = document.getElementById("lin");
            function xxx03(p) {
                sv.innerHTML = p;
            }

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Ох, как Ява простым пацанам мозги то засирает, айяйяй. Не зря они по 200тыщ зарплаты получают, получали бы меньше - лечица бы ненашто было. Бидняшки.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

DetSimen пишет:

Ох, как Ява простым пацанам мозги то засирает, айяйяй. Не зря они по 200тыщ зарплаты получают, получали бы меньше - лечица бы ненашто было. Бидняшки.

если есть что конкретно сказть - слушаю, если хочется флудить - тут не место

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Ах, Большая Белая Госпожа, прости бедного раба своего. Я так большенебуду. 

JonHappy1
Offline
Зарегистрирован: 11.06.2018

DetSimen пишет:

Ах, Большая Белая Госпожа, прости бедного раба своего. Я так большенебуду. 

так есть что конкретно?

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

JonHappy1 пишет:

если хочется флудить - тут не место

Ты уверен, что вправе указывать уважаемым на форуме людям их место? Может тебе самому указать?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

что надо сказать конкретно, Вам уже сказали в самом начале топика. Там практически "добавить" нечего. ДедСемен - прав, и в общем-то у меня попкорн тоже уже закончился читать ваши опусы "джависта". Раньше как-то ещё смотрел .. эх, здря в свое время принципиально отказался изучать жабу .. а теперь, почитав Вас, хорошо представляю что "ах какой был мудрый в юнности"!

Не переживайте. "Человек - подобен колбасе, чем его начинят - то он и носит в себе" (с) Козьма Прутков. Точно также как Вы сейчас, лет надцать назад осваивал реляционную Алгебру и скуль .. мозги выворачивает наоборот, просто "наотмашь". :)

JonHappy1
Offline
Зарегистрирован: 11.06.2018

дак если добавить нечего - зачем флудить?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

JonHappy1 пишет:

дак если добавить нечего - зачем флудить?

У каждого на то свои причины. Хочет человек пофлудить, и флудит. Вам, может быть и незачем, а другому, наверное, есть зачем, если деалет это.

b707
Offline
Зарегистрирован: 26.05.2017

JonHappy1 пишет:

дак если добавить нечего - зачем флудить?

в принципе, действительно, продолжать особо смысла нет.

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

JonHappy1
Offline
Зарегистрирован: 11.06.2018

Цитата:
У каждого на то свои причины. Хочет человек пофлудить, и флудит. Вам, может быть и незачем, а другому, наверное, есть зачем, если деалет это.
но его флуд начался с киданием какашек ....

Цитата:
В чем прав Логик - вы делаете ужасный костыль.
в чем костыль? в том что наглядно можно вызвать функцию по имени?  я показал код в котором элементано послеживается похождение инфы. то что считаешь только счас удобно - так это проверено уже во множестве поектов, поэтому и применяю к ардуине.

а флуд он разный бывает, есть и по делу , а есть в оскорбление...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

JonHappy1 пишет:
но его флуд начался с киданием какашек ....
И что? Ну, хочет человек покидаться какашками. Может он для этого сюда пришёл, типа настроение такое. В чём проблема-то? Это Спарта Интернет, если чо.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

Цитата:
]И что? Ну, хочет человек покидаться какашками. Может он для этого сюда пришёл, типа настроение такое. В чём проблема-то? Это Спарта Интернет, если чо.
т.е. кидаться можно, а указать на то , что это плохо - нельзя?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Што есь какашки с твоей точки зрения?  Нельзя про явапроггеров говорить плахова?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

JonHappy1 пишет:
указать на то , что это плохо - нельзя?
А разве я где-то говорил, что нельзя? Вы спросили "зачем флудить" - я Вам ответил.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

DetSimen пишет:

Што есь какашки 

Их много разновидностей. Вот небольшая классификация за 33 категорий.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Хорошо быть кошкою,
Хорошо — собакою:
Где хочу – пописаю,
Где хочу – покакаю.
Ямку лапой вырою,
Положу какашку я, —
И не надо попу мне
Вытирать бумажкою.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

DetSimen пишет:

Што есь какашки с твоей точки зрения?  Нельзя про явапроггеров говорить плахова?

по любого не стоит говорить плохо.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Мда.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

DetSimen пишет:

Мда.

надеюсь, это относилось к посту #91? Кстати, вторую часть я никогда не слышал. Думал, что первая - это и всё :)