pechkin: (сумасшедший домик на вершине горы)
Не пытайся больше сделать так:
public struct Unit
{
    public int ID;
    public int Value;
}

List<Unit> list;
list[i].Value = x;

Ничего не получится. Почему нужно Unit сделать классом, мы оставляем как упражнение пытливому читателю.
pechkin: (сумасшедший домик на вершине горы)
Нужно, во-первых, проверить, что нужные <DeploymentItem /> имеются в секции <Deployment> релевантного *.testsettings файла, а, во-вторых, закрыть и снова открыть Visual Studio.

Kto tego nie zrozumiał
żyć wiecznie nie będzie umiał.
Kto tego nie rozważył,
kto tego nie rozważył
w piekle się będzie smażył.
pechkin: (сумасшедший домик на вершине горы)
Не столько для помощи, сколько чтобы упорядочить в голове.
Итак, имеется svn репозиторий, сидящий на машине 192.168.1.2 на /home/pechkin/svn/www.
На эту машину проброшен на раутере порт 3690. На одной страничке говорили пробросить порт 2690, пробросил и его на всякий случай.
Раутер каждые сколько-то минут пинает no-ip.org, чтобы обновить айпи хоста s-pechkin.no-ip.org.
С pechkin.rinet.ru нужно обратиться к этому репозиторию.
Делаю

svn ls svn+ssh://s-pechkin.no-ip.org/home/pechkin/svn/www
pechkin@s-pechkin.no-ip.org's password:
svn: No repository found in 'svn+ssh://s-pechkin.no-ip.org/home/pechkin/svn/www'

Судя по тому, что запрашивает пароль, ssh работает; значит, до машины с репозиторием доходим. Так?

Значит, в урле что-то не так? адрес неверный?

Сходил на соседнюю машину, дернул оттуда - работает:

pechkin@userver:~$ svn ls svn+ssh://schkaff/home/pechkin/svn/www
pechkin@schkaff's password:
branches/
dev/
tags/
trunk/

Вот чего это? Как еще можно диагностировать?

UPDATE: починил. Неправильный порт в sshd_config на машине schkaff.
pechkin: (сумасшедший домик на вершине горы)
И еще, джентльмены: если вам дороги жизнь и рассудок, не перегружайте оператор Equals() в классе, объекту которого предстоит сделаться ключом для Dictionary. Даже если вы достаточно предусмотрительны и не забыли перегрузить правильным образом метод GetHashCode(). Не делайте этого, право же, оно того не стоит.
pechkin: (сумасшедший домик на вершине горы)
Хочу убедиться, что конструктор Model(ushort[] arg) таки да вызывает SetSomething(arg).

internal class ModelMock_Ctors : Model
{
 public ushort[] actualArg;

 public ModelMock_Ctors(ushort[] arg)
  : base(arg)
 { }

 public override void SetSomething(ushort[] arg)
 {
  actualArg = arg;
 }
}

public class Model : IDevice
{
 public Model(ushort[] arg)
 {
  SetSomething(arg)
 }


 public virtual void SetSomething(ushort[] arg)
 {
  //...
 }
}

[TestClass()]
public class ModelTest
{
 [TestMethod]
 public void ModelConstructorTest()
 {
  ushort[] expected = new ushort[] 
  { 
   //...
  };  

  ModelMock_Ctors target = new ModelMock_Ctors(expected);
  CollectionAssert.AreEqual(expected, target.actualNVM);
 }
}



У меня устойчивое ощущение, что существует не самодельный способ сделать это, но я не могу его найти. Наверно, это Moq, но у этой, по всем отзывам замечательной, библиотеки, похоже, отсутствует документация.
pechkin: (сумасшедший домик на вершине горы)
Давно уж я заметил, что по коду можно много сказать о том, кто его написал. Видел я коды параноидальные, которые стремились проверить все возможные условия, поймать все возможные внештатные ситуации, включая случай, если единица равняется нулю. Видел я коды, страдающие рассеянием внимания, в которых ни одна функция не делала что-то одно, а делала несколько не связанных дел. Попадались коды, чрезмерно полагающиеся на окружение, и коды, страдающие аутизмом в той или иной степени. Имена переменных многое могут рассказать, и названия функций. В одном коде все сущности именовались "чего-нибудь handler", а в другом - "чего-нибудь engine", хотя в них очень мало что двигалось на самом деле. Видел и восхищался кодами, кристалльно ясными и четкими; видел коды безумно путаные, сводившиеся к почти ничему.

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

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

То есть, в мире моего кода предметы слишком много на себя берут, и тем, кто этими предметами пользуется, становится малость не по себе. Слишком умные предметы, заумные даже.

Я сказал: наверно, это говорит о склонности делегировать ответственность. Мне сказали, что это само по себе стремление для программиста правильное, но вот так все-таки делать не надо. Надо переделать, сделать код более прозрачным и управляемым.

Вот, пошел думать.
pechkin: (сумасшедший домик на вершине горы)
Даже я это давно уже знаю, что работать правильно в итоге получается быстрее, чем работать быстро. Но каждый раз удивляюсь невольно, когда первый модуль пишешь неделю, со всем его TDD, с дизайнами такими и сякими, меняешь, гоняешь, и кажется, что это никогда не кончится, но вдруг оно кончается, а второй и третий модули добавляешь за два часа.
pechkin: (сумасшедший домик на вершине горы)
Я поторопился стереть пост про PHP на радостях, что все будто бы заработало, а оно нет.

Ситуация такая: попросили сделать интеграцию между BeanStalk и Mantis. Mantis бежит на удаленном сервере. К нему приходит пост-реквест с мессагой от Subversion, у него php-скрипт, который ее парсит и с параметрами вызывает другой скрипт. Когда мантис бежал на винде в нашей локалке, команда вызова этого скрипта была такой:

shell_exec("echo -n \"$message\" | C:\php\php.exe checkin.php $author 2>&1");

и работала. Потом мантис переехал на юникс-сервер. Я написал:

shell_exec("echo -n \"$message\" | /usr/bin/php ./checkin.php $author 2>&1");

и приготовился радоваться, ан шиш. Мне то говорится "sh: fork: retry: Resource temporarily unavailable", что объяснимо, хотя и непонятно, как преодолевать (не хочется переписывать мантисовский хозяйский скрипт, хер их знает, для чего еще он у них используется. То, если вдруг прорвется дальше, возникает следующая проблема: в том скрипте, который вызывается, есть проверка:

# Make sure this script doesn't run via the webserver
if( php_sapi_name() != 'cli' ) {
 echo "checkin.php is not allowed to run through the webserver.\n";
 exit( 1 );
}


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

Кстати, вообще довольно странная картина. Весь приемный скрипт, которому посылается реквест, выглядит так:

<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL | E_STRICT);
date_default_timezone_set('UTC');

$json = rawurldecode(file_get_contents('php://input'));
$data = json_decode($json);

$author = $data->{'author'};
$message = $data->{'message'};

echo("Author: $author; Message: $message\n");

$output = shell_exec("echo -n \"$message\" | /usr/bin/php ./checkin.php $author 2>&1");
echo(date('Y-m-d H:i:s') . " checkin.php: $output\n");
?>


(Кое-что выкинуто, но суть такова)
Результат его вызова выглядит так:

Read more... )
Что за трудновыразимая херня происходит у меня со вводом-выводом?

Вопрос не очень срочный, поскольку задачу эту отложили. Как пойму, в чем дело, так и починю.
pechkin: (Default)
Я перенес некоторые материалы на сайте из директории a в директорию b. Хочу, чтобы те, у кого остались старые линки, тоже попадали теперь по запросу site/a/index.html в site/b/index.html. Но при этом не хочу прописывать адрес хоста, хочу пользоваться относительными линками. Что ли, mod_rewrite такого не позволяет, или я о чем-то не знаю? Я думал,

RewriteEngine on
RewriteRule ^(.*)/a/(.*)$ $1/b/$2 [NC,L,R=301]

будет работать. А оно нет.

UPD: RTFM. 

RewriteEngine on
RewriteRule ^a/(.*)$ b/$1 [NC,R=301]


pechkin: (Default)
Ура, сделано еще одно тихое и прекрасное не имеющее практического смысла в обозримой реальности дело. Написан "индексатор" для "Jubilate Agno" Смарта. Он лежит в рабочем состоянии здесь.

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

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

Эту проблему я пока не знаю, как решить.

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

В общем, думать надо.

Каждый желающий может попробовать посоставлять индексы. Интерфейс там довольно интуитивный, мне так кажется. Вводишь термин, вводишь регекс, указываешь, с какого фрагмента начинать (я не пробовал с других, кроме первого), тыкаешь кнопочку.
pechkin: (Default)
Если @Ajax.ActionLink не рендерит аттрибут href (оставляет его пустым) - это значит, что маппинг, который ты хочешь получить с этого линка, не существует. Лезь в global.asax и добавляй его в RouteCollection. Или проверяй, почему он из того, что у тебя там написано, не вычисляется.

Вот было бы славно придумать какую-нибудь тестульку, чтобы проходила по всем путям, которые тебе нужны, и проверяла, вычисляются ли они из RouteCollection.
pechkin: (Default)
Есть такая таблица, для связей объектов, и в ней два поля, куда вписываются id объектов. Нужны такие ограничения:

1. Нельзя привязать объект сам к себе: ALTER TABLE [dbo].[Relations] ADD CHECK (GUID1 <> GUID2)
2. Нельзя привязать один объект к другому больше, чем один раз: CREATE UNIQUE INDEX [GUIDsUnique] ON [dbo].[Relations]
([GUID1] ASC, [GUID2] ASC) 
3. Нельзя привязать один объект к другому, если другой уже привязан к первому. Как это реализовать на уровне базы данных?
4. Не забыл ли я чего?
UPD: Видимо, я сделаю так: 

-- проверка привязки объекта к себе самому
ALTER TABLE [dbo].[Relations] ADD CHECK (GUID1 <> GUID2)
-- проверка повторной привязки 
CREATE UNIQUE INDEX [GUIDsUnique] ON [dbo].[Relations] ([GUID1] ASC, [GUID2] ASC) 
-- триггер на добавление/изменение, который просто уберет из таблицы все (максимум одну) перевернутые пары. Они ведь по смыслу совершенно идентичны той, которая только что появилась

Я не ошибся нигде?

UPD: еще чуть более элегантное решение: не надо что-то делать, если не надо это делать:

ALTER TRIGGER [dbo].[CheckReversedPairs_Insert]
ON [dbo].[Call_Related]
INSTEAD OF INSERT
AS
BEGIN
if 0 = (select count(*)
    from call_related, inserted 
    where call_related.callguid1=inserted.callguid2 and call_related.callguid2=inserted.callguid1)
insert into call_related 
    select * from inserted
END

Осталось только сочинить запрос, который проверит существующую уже таблицу на перевернутые пары. Делов-то. И обедать.

UPD: Сытое брюхо подсказало выход:

SELECT Call_Related.*
FROM     Call_Related INNER JOIN
                  Call_Related AS Call_Related_1 ON Call_Related.CallGUID1 = Call_Related_1.CallGUID2 AND Call_Related.CallGUID2 = Call_Related_1.CallGUID1 AND 
                  Call_Related.CallGUID1 < Call_Related.CallGUID2
pechkin: (Default)
По-моему, это очень сильное колдунство - заменить 

StringBuilder sb = new StringBuilder("{");
foreach (var company in AvailableCompanies)
{
       sb.AppendFormat("\"{0}\":[{1}],", company.CompanyGUID, 
              string.Join(",", 
              AvailableCalls.Where(call => call.CompanyGUID.Equals(company.CompanyGUID)).ToArray()
              .Select(c=>string.Format("\"{0}\"", c.CallGUID))));
}
sb.Remove(sb.Length - 1, 1);
sb.Append("}");
return sb.ToString();

на

return Memo.User.Calls.GroupBy(call => call.CompanyGUID)
     .ToDictionary(group => group.Key.Value.ToString(),
          group => new JsonArray(group.Select(call => new JsonPrimitive(call.CallGUID.ToString()))))
     .AsEnumerable()
     .ToString();
pechkin: (Default)
Кто-нибудь когда-нибудь делал логин фейсбук-юзеров на свой сайт - на клиенте, JavaScript SDK? Есть вопрос, документация не помогает.
pechkin: (Default)
Ищу себе ORM, который был бы симпатичнее EF, но все умел бы. В поисках натыкаюсь на такое:

<q>SubSonic will be your friend, will never tell you you're dumb, and will do whatever it takes to get you home earlier, convincing you that too many hours spent at work turn you into a potato.</q>

Надо посмотреть.
pechkin: (Default)
На заре 2012 года мне пришла в голову светлая идея, что "Эльфийский словарь" следует загнать в вики. Потому что это то, чем он, в сущности, является, и перекрестные линки лучше всего делать именно в той форме, она проста и ненапряжна ни для читателя, ни для меня.

Встал выбор, какой движок выбрать. Хоститься это все может либо на ринете, либо на третьей стороне. (либо у меня дома, под лестницей, но это несерьезно.) Третьей стороне я не очень доверяю. На ринете я не очень знаю, как поставить вики-движок. Если есть такие, что можно раскатать у меня дома, а потом просто залить на ринет файлы - это будет ура, потому что фтпить туда я умею (а sshом попробовал зайти, пароль не подошел, я подумал, что что-то делаю не так, и сник. А то бы конечно.)

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

Да, и очень желательно бесплатно, потому что, как бы, традиция такая.
pechkin: (Default)
Может быть, я не настоящий сварщик, но вот я с некоторым изумлением взираю на работающую конструкцию: 

function MfNotification() {
    this.show = function(body, onClose, title, txtOk, iconSrc, txtCancel, customSetup) {
        this.message.html(body);
        this.title.html(title || MfNotification.title);
        this.btnOk.html(txtOk || MfNotification.txtOk);
        this.btnOk.bind("click", true, onClose);
        if (iconSrc.length > 0) {
            this.icon.attr("src", iconSrc);
            this.icon.show();
        }
        if (customSetup)
            customSetup(this, arguments);
        this.popup.show();
    }
}

MfNotification.Confirm = function(body, onClose, title, txtOk, iconSrc, txtCancel) { MfNotification.getInstance().show(body, onClose, title, txtOk, iconSrc || MfNotification.iconSrc_confirm, txtCancel,
    function(instance, [body, onClose, title, txtOk, txtCancel, iconSrc]) {
        instance.btnCancel.html(txtCancel || MfNotification.txtCancel);
        instance.btnCancel.bind("click", false, onClose);
        instance.btnCancel.show();
    });
}


Я не знал, что джаваскрипт умеет так много гитик.
pechkin: (Default)
 Дали задание создать аппликацию по работе с подгруженным HTMLом в Conduit.

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

Мизер технических деталей и вообще всяческий смысл тонет во всякого рода булшыте о том, как же это все на самом легко, очень легко, эффективно, быстро и популярно сделать, и 270 миллионов юзеров немедленно скачают эту аппликацию и начнут ею эффективно пользоваться для увеличения своего удовольствия от функционирования в сети и к вящей монетизации вашего уникального этого, как его... брендинга. При этом, чтобы выяснить минимальную техническую подробность, выбрать, с чего надо начинать, пришлось лично переговорить с суппортером - который, разумеется, именуется Специалистом по Увеличению Пользовательского Удовлетворения.

О, дивный новый мир. Хочу назад в двадцатый век, писать на перле под линукс вещи, которые реально нужны реальным людям, и они знают, для чего. Тогда все слова означали что-то другое - loyalty, engagement, optimization, fun...

"Did you know?
Toolbars with radio are 20% more popular than others!"

Явно пора искать другую работу.
pechkin: (Default)
проблема конфигураций в дотнете состоит в том, что информация о том, что нужно серверному проекту, содержится в самом серверном проекте (определения конфиг-секции, которую он будет юзать); информация о том, что серверный проект юзается, содержится в клиентном проекте (его зависимости); а информация о том, что юзается клиентный проект, находится где-то в зависимостях аппликации. Если бы можно было пройтись по дереву зависимостей, найти все клиентные проекты, собрать все их серверные проекты и просигнализировать аппликации, что она должна включить в свою конфигурацию их секции, можно было бы не волноваться, что что-то забыл.

Пока что я умею в пост-билд каждого серверного проекта вставлять подъем флажка, если ему нужна конфиг-секция. Можно даже скелет этой секции копировать, с указанием типа и библиотеки для последующего
тага. Это как бы проход по зависимостям.

Теперь в пре-билде аппликации нужно все эти флажки посмотреть и завалить билд, если не хватает соответствующих конфиг-секций (или их инклюдов, а сами секции можно скопировать в $(TargetDir) из какой-нибудь $(SolutionDir) подпапки). Вот только как? Перловый скрипт (первая мысль)? екзешник, анализирующий XML?

Лень скука, рассеянность и плохая память - величайшие двигатели программерского прогресса.
pechkin: (Default)
 У меня нет профессионального блога, но я только что сделал важное открытие, которое может кому-нибудь сэкономить немало часов жизни и волос на голове.

Настройки SMTP-сервера для абонента Google Apps, приведенные здесь, не соответствуют истине. Настройки, которые работают - вот какие:
сервер smtp.googlemail.com 
 порт587 

July 2017

S M T W T F S
      1
23456 78
9 101112131415
16 171819 202122
23 24 2526272829
3031     

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 26th, 2017 12:36 pm
Powered by Dreamwidth Studios