2015-03-05

Из анонса новой CRT в Visual Studio

...
The "best" example of this maintainability problem could be found in the old implementation of the printf family of functions. The CRT provides 142 different variations of printf, but most of the behavior is the same for all of the functions, so there are a set of common implementation functions that do the bulk of the work. These common implementation functions were all defined in output.c in the CRT sources(1). This 2,696 line file had 223 conditionally compiled regions of code (#ifdef, #else, etc.), over half of which were in a single 1,400 line function. This file was compiled 12 different ways to generate all of the common implementation functions. 
...
We have converted most of the CRT sources to compile as C++, enabling us to replace many ugly C idioms with simpler and more advanced C++ constructs. The publicly callable functions are still declared as C functions, of course (extern "C" in C++), so they can still be called from C. But internally we now take full advantage of the C++ language and its many useful features.
...
Before this refactoring, the sprintf functions, which write formatted data to a character buffer, were implemented by wrapping the result buffer in a temporary FILE object and then deferring to the equivalent fprintf function. 

2014-12-25

что мертво -- умереть не может

На дворе без малого 2015 год, а люди все еще используют VC6 (прислали сделанное тестовое).

2014-12-04

Callbacks vs promises

Добавил в текущий проект промисы. Для сравнения

До:
-(void) p_pluckHamsSinceLastPluckWithCompletion:(BarPluckHamsCompletion) completion
{
  NSDate * date = [NSUserDefaults standardUserDefaults].lastPluckDate;

  XXXHamPlucker plucker = ^(XXXPluckSession * session, XXXFoo *foo, XXXPluckConsumer consumer) {
    [session searchBoosSinceDate:date withFoo:foo completion:^(NSError *error, NSIndexSet * boos) {
      if (error)
        return consumer(error, nil);
      [Bar filterBoos:boos withFoo:foo completion:^(NSIndexSet *boos) {
        [session pluckHamsWithBoos:boos withFoo:foo completion:^(NSError * error, NSArray * hams) {
          if (error)
            return consumer(error, nil);
          [Bar filterHams:hams inFoo:foo completion:^(NSArray *hams) {
            consumer(nil, hams);
          }];
        }];
      }];
    }];
  };

  [self p_pluckHamsUsingPlucker:plucker completionHandler:completion];
}

После
-(XXXPromise *) p_pluckHamsSinceLastPluck {
  NSDate * date = [NSUserDefaults standardUserDefaults].lastPluckDate;

  XXXHamPlucker plucker = ^(XXXPluckSession * session, XXXFoo * foo) {
    XXXPromise * promise = [session searchBoosSinceDate:date withFoo:foo];
    return promise.thenPromise(^(NSIndexSet * boos){
      return [Bar filterBoos:boos withFoo:foo];
    }).thenPromise(^(NSIndexSet * boos){
      return [session pluckHamsWithBoos:boos withFoo:foo];
    }).thenPromise(^(NSArray * hams) {
      return [Bar filterHams:hams withFoo:foo];
    });
  };

  return [self p_pluckHamsUsing:plucker];
}

Промисы свои, написал часа за 3-4. Смотрел RXPromise и PromiseKit, но они не умеют то, что мне нужно.

2014-07-22

some fancy swift errors

5> [1,2,3].map { $1 * 10 }
<repl>:5:9: error: type '(($T7, ($T7, $T8) -> ($T7, $T8) -> $T6) -> ($T7, ($T7, $T8) -> $T6) -> $T6, (($T7, $T8) -> ($T7, $T8) -> $T6, $T8) -> (($T7, $T8) -> $T6, $T8) -> $T6)' does not conform to protocol 'IntegerLiteralConvertible'
6> let x = [1,2,3]
x: [Int] = 3 values {
  [0] = 1
  [1] = 2
  [2] = 3
}
7> x.map { $1 * 10 }
<REPL>:8:7: error: 'Int' is not a subtype of '(($T5, ($T5, $T6) -> ($T5, $T6) -> $T4) -> ($T5, ($T5, $T6) -> $T4) -> $T4, (($T5, $T6) -> ($T5, $T6) -> $T4, $T6) -> (($T5, $T6) -> $T4, $T6) -> $T4)'
x.map { $1 }
и эти люди ругают С++ за сообщения об ошибках...
PS. Если что, правильный код --  x.map { $0 * 10 }

2014-05-15

Что может быть проще емейла...

сотрудник:
тебе не приходилось на плюсах делать проверку на типа валидный email
­
bitfield:
в инете есть страшные регекспы
­
сотрудник:
я их боюсь
думал может что готовое есть
­
bitfield:
я б не парился, проверял на x@y.z where x,y,z in [a-zA-Z0-9.+-]
­
сотрудник:
так и сделаю
­
bitfield:
вообще-то, там все грустно и запущено.
­
сотрудник:
да уж, я читал про 1000 символьный регексп на перле
­
bitfield:
тесты к одному чекеру

[("\"Abc\\@def\"@example.com",True),
("\"Fred Bloggs\"@example.com",True),
("\"Joe\\Blow\"@example.com",True),
("\"Abc@def\"@example.com",True),
("customer/department=shipping@example.com",True),
("$A12345@example.com",True),
("!def!xyz%abc@example.com",True),
("_somename@example.com",True),
("NotAnEmail",False),
("@NotAnEmail",False),
("\"test\\\\blah\"@example.com",True),
("\"test\\blah\"@example.com",True),
-- # Phil gets false for this, which I think is wrong
-- # (Dominic Sayers notes the same at the end of the comment thread)
("\"test\\\rblah\"@example.com",True),
("\"test\rblah\"@example.com",False),
("\"test\\\"blah\"@example.com",True),
("\"test\"blah\"@example.com",False),
("customer/department@example.com",True),
("$A12345@example.com",True),
("!def!xyz%abc@example.com",True),
("_Yosemite.Sam@example.com",True),
("~@example.com",True),
(".wooly@example.com",False),
("wo..oly@example.com",False),
("pootietang.@example.com",False),
(".@example.com",False),
("\"Austin@Powers\"@example.com",True),
("Ima.Fool@example.com",True),
("\"Ima.Fool\"@example.com",False),
("\"Ima Fool\"@example.com",False),
("Ima Fool@example.com",False)]
­
сотрудник:
ааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааа!!!!!!!!!!!!!!!!!!!!!!!!!!
­
bitfield:
самая жесть, в имейле могут быть круглые скобки, и они должны совпадать
isValid "((lol)porges(()comme(nests)nt())@example.com" == False
isValid "((lol))porges(()comme(nests)nt())@example.com" == True
isValid "\"s\\\0\"@example.com" == True
-- # "s\NUL"@example.com, where NUL is actually the
-- # null character! Yep, can't strlen() on email addresses...
­
сотрудник:
чудесно
­
bitfield:
да я сам в ах^Wвосхищении

2014-01-03

Яббл тоже страдает NIH-синдромом.

Собирал одну С-библиотеку. Как водится, 100500 предупреждений, которыми никто не парится.
Обратил внимание на ряд "XXX is deprecated, first deprecated in OS X 10.7".
Начал гуглить -- в 2011 они объявили "старое" криптоапи устаревшим (наверное, нашли в нем Фатальный Недостаток TM). Взамен рекомендуют CF-api с блекджеком и шл^W^W^W блоками и пайплайнингом операций. Причем оно доступно только в OS X, для iOS есть "CommonCrypto", почти совместимый с OpenSSL.
P.S. да, я слоупок :)

2013-12-03

одного потока хватит всем...

В GDI+ внутри Graphics.DrawImage лочится критическая секция. Поэтому  заводить более одного рабочего потока для рисования -- бессмысленно. А если еще и гуй отрисовывается картинками, то вообще фигня получается.