?

Log in

State of NJ does not recognize leap years

Originally published at www.ikriv.com. Please leave any comments there.

Number of days for all residences cannot exceed 365.”. This is the error I got from NJ division of taxation web site when I tried to enter how many days I lived in each residence in 2016. I guess they just take a day off on February 29…

Метки:

Don’t give me apples that are not red!

Originally published at www.ikriv.com. Please leave any comments there.

I have just stumbled on a beautiful example of a double negative in our code. We have a function that returns a list of object, and it takes a “filterFunction” as a parameter:

List<Apple> GetApples(Function<Apple,bool> filterFunction)

The trouble is, filterFunction works as exclusion function: is is supposed to return true for objects to be thrown out, and false for objects to be kept in the list. So, effectively, instead of saying “give me only red apples” you have to say “don’t give me apples that are not red”. Logically it’s the same thing, but human brain is not designed to easily handle double negatives.

For this reason, I always ask people not to use variable names like “IsNotValidUser” where “false” designates a valid user, and “true” means an invalid user. A flag named “IsValidUser” with reversed values is much easier to understand. However, I’ve never seen the “is not” logic applied to filter functions before. Maybe it has something to do with popularity of functional programming…

Метки:

Originally published at www.ikriv.com. Please leave any comments there.

I remember how Linux community used to scoff at Windows for constant restarts and boasted ever longer uptimes: “my server has been running without reboot for 5 years!”. Guess what, yesterday I logged in to my Ubuntu server to be greeted with an “updates are installed, restart is required” message. Apparently, this comes with the territory: automatic updates are required to fend off hackers and patch vulnerabilities, and with automatic updates come restarts. Welcome to the grown-up world, Linux!

Метки:

JavaScript WTF #1

Originally published at www.ikriv.com. Please leave any comments there.

In ECMA Script 6 toString() function can throw an exception. This makes generating debug output a treacherous minefield. In all other languages I know toString() on built-in objects is safe, and custom toString() implementations that throw an exception are not welcome.

Consider the following code:

function *generator() { yield 42; }
var it = generator();
console.log(it.constructor); // Prints "GeneratorFunction {}"
console.log(it.constructor.toString()); // TypeError: Function.prototype.toString is not generic

So, it actually is possible to print the object to the debug output, but only by itself, no manipulation is allowed. The error message is also quite cryptic: what do they exactly mean by ‘not generic’ and why should I care?

This may seem like a minor annoyance, but I believe it is so brutally violates the rule of least astonishment, that it proudly occupies #1 place among other JavaScript WTFs. In sane languages toString() should not normally fail, at least not for built-in classes. It may, of course, fail with something like OutOfMemoryException, but that’s not what most people would call “normally”. If toString() can throw, I am forced to write a try/catch around every toString() when dealing with unknown objects, and this is, frankly, less than ideal.

Nuget shenanigans

Originally published at www.ikriv.com. Please leave any comments there.

We have added some Reactive Extensions support to our software. All went well until it went into the automated build.

Nuget version 3.3.0.212 could not handle System.Reactive.Core package: it would (falsely) claim that the package could not be found. Interestingly enough, Nuget does not seem to have an option to show where it was looking for the package and why exactly the package cannot be found. In reality, the package was found and even downloaded to the cache, but then Nuget somehow could not deal with it properly.

After we upgraded to Nuget version 3.5.0.1938, this problem disappeared: System.Reactive.Core now miraculously can be found. However, we were up for another surprise: we started to get “file not found” errors when trying to access the nuget package file from the build script. It turns out that in Nuget 3.3, when we specified package version as 1.2.3.0, it would create file named MyProduct-1.2.3.0.nupkg. However, in Nuget 3.5 under the same circumstances the packge file is named MyProduct-1.2.3.nupkg, for compatibility with semver. As a result, our build script is unable to find the nuget package, and, as far as I can tell, there is no switch to restore the old behavior.

Well done, Nuget, well done!

Метки:

Родина-има зовет

Сходил сегодня в израильское консульство за новым паспортом. Оказалось, что тем, кто не был в Израиле больше 10 лет, паспорт дают только на год. Сказали - захочешь поехать в Израиль, приходи, мы его продлим. Бесплатно. А как съездишь в Израиль - продлим на 10 лет как белому человеку.

Почитал в Интернете - это они еще по-божески со мной поступили. Согласно правилам, таким национал-богдим как я, которые мамку-моледет забыли, паспорт вообще не положен, а положено что-то типа свидетельства о возвращении, да и то если покажешь оплаченый прямой (!) билет в Израиль (а если нет прямого? из какой-нибудь Японии в Израиль самолеты напрямую не летают; ну да жестокость израильских законов обеспечивается необязательностью их исполнения...).

А мы вот Путина ругаем. Россия (пока) дает паспорт на 10 лет без звука, был ты там или не был.

Одно радует - в отличие от консульства РФ все искренне вежливые, терпеливые и разговаривают как мама с детьми.

Originally published at www.ikriv.com. Please leave any comments there.

I had to create a dump of a misbehaving process on Windows Server 2012 using Task Manager. Not only did it tell me where it put the dump, the file location was selectable and copyable! Kudos to Microsoft. From previous experience, I expected a simple message “dump created” and prepared to do some googling to find out where the heck it went to. These small things tend to eat a lot of time, and finally Microsoft has realized that. I’m impressed.
dumplocation

Метки:

Whose lives matter?

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

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

Коммунисты произвели лично на меня наиболее сильное впечатление - я как-то не ожидал встретить их в Америке в товарных количествах.

Расисты:


Коммунисты:


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

Originally published at www.ikriv.com. Please leave any comments there.

…Continued from Part 1.

Arrow functions

ES6 introduces arrow functions, which can take several forms:

()=>expression
x=>expression
(x,y)=>expression
()=>{operators}
x=>{operators}
(x,y)=>{operators}

Besides being a shorter notation for function(), arrow functions have special rule for this. They inherit this from their immediate lexical context. This makes arrow functions ideal for callbacks. Consider the following code:

'use strict'

var obj = {
    value: 42,
    delayInc() { 
         setTimeout(function() { 
             console.log("Incremented value: " + ++this.value); // oops...
             console.log(this);
	 }, 10);
    },
}
obj.delayInc();

This prints

Incremented value: NaN
Timeout {
  _called: true,
  _idleTimeout: 10,
  _idlePrev: null,
  _idleNext: null,
  _idleStart: 96,
  _onTimeout: [Function],
  _timerArgs: undefined,
  _repeat: null,
  value: NaN }

Why NaN? The hint is in the subsequent lines: this value of the callback is (somewhat arbitrarily) set to a Timeout object. In other languages, the Timeout object would probably have been passed as a parameter, but in JavaScript we have this, which can be set to anything, so why not use it? Consequently, this.x in the callback refers to Timeout.x, which is undefined, and not to obj.x as one might have expected. Incrementing undefined yields NaN, and obj.x remains unchanged.

Pre-EcmaScript 6 fix to this problem was to introduce an extra variable:

'use strict'

var obj = {
    value: 42,
    delayInc() { 
         var $this = this;
         setTimeout(function() { 
             console.log("Incremented value: " + ++$this.value); 
             console.log($this);
	 }, 10);
    },
}

obj.delayInc();

This works as expected:

Incremented value: 43
{ value: 43, delayInc: [Function: delayInc] }

With arrow functions we can get rid of the extra variable and shorten the code:

'use strict'

var obj = {
    value: 42,
    delayInc() { 
         setTimeout(() => { 
             console.log(this);
             console.log(++this.value); 
	 }, 10);
    },
}

obj.delayInc();

This snippet behaves exactly like previous one, printing

Incremented value: 43
{ value: 43, delayInc: [Function: delayInc] }

Unfortunately, inheriting this from the lexical context makes arrow functions unsuitable in some other contexts. Consider:

'use strict'

var obj = {
    value: 42,
    inc: ()=>++this.value,
    inc2() { return ++this.value; }
}

console.log(obj.inc(), obj.inc2());

This prints

NaN 43

The arrow function inc() takes this from the surrounding context, setting it to the global object. Similarly looking regular member function inc2() has its this set to obj at the time of invocation.

Unlike Java and C#, where lambdas are nearly equivalent to regular methods, in JavaScript they behave quite differently.

This in static context

In most languages “static” methods don’t have this. JavaScript is, again, different:

class Foo {
    static f() { 
	console.log(this, this === Foo);
    }
}

Foo.f();

This prints

[Function: Foo] true

In static contexts this points to the surrounding class, which is actually a function.

Conclusion

Simply put, there are two many rules governing the value of this in JavaScript. If I write a simple function printing this, it can print virtually anything, depending on how we invoke it, and it is by design.

function f() { console.log(this); }

f();                      // 'global object' or undefined in strict mode
var obj = { f }; obj.f(); // obj
new f();                  // newly created object of type f
f.call({x:42});           // { x: 42 }
f.bind({x:42})();         // { x: 42 }

ES6 arrow and static functions add even more rules and special cases.

Such versatility makes JavaScript this a really powerful mechanism. Think through how many hoops you would have to jump to call method of one C# class on an instance of another C# class. On the other hand, why would you want to do it? Even if C# had such a feature, it probably would have been considered extremely dangerous and not suitable for use under normal circumstances. Anyway, huge power and flexibility of JavaScript this comes at the expense of simplicity and safety: it provides a number of excellent devices to shoot oneself in the foot.

Originally published at www.ikriv.com. Please leave any comments there.

Java language specification defines “this” keyword in one sentence. EcmaScript 6 definition of “this” is about a page of pseudo-code spread over several paragraphs, and there is a good reason for that.

JavaScript’s this is defined by chain of nested “execution contexts”. It may depend on both the execution path and the static location of the caller in code, and can refer to virtually anything, or nothing at all. This makes this arguably the most confusing concept in the language. The list of gotchas related to “this” is long and quite impressive: so long in fact, that I had to divide this WTF into parts.

Undefined “this” for indirect method calls

In JavaScript this is set to undefined inside free function calls (in strict mode), and to the method-holding object inside method calls. It makes perfect sense, but the caveat is that if we call an expression whose value is a function, this will always be undefined, even if said function is actually a method of some object. Consider the following code:

'use strict'
var obj = { 
    x:42, 
    printX() { console.log(this.x); } // method
};

function invoke(action) { action(); /* free call */ }

obj.printX();                 // 42
invoke(obj.printX);           // Cannot read property 'x' of undefined

The call on line 9 is a method call, it works as expected. The call on line 10 passes the result of the expression obj.printX as a parameter to the invoke() function. In this case obj is only used to retrieve the pointer to the printX function, and then discarded. When printX is called on line 7 via the action variable, it is considered a free function call, not a method call. Therefore, its “this” pointer is set to undefined, hence the error.

This “feature” caused so much pain, that EcmaScript 6 defined a special work-around for it in the form of arrow functions, to be discussed in part 2.

In certain cases, it may be tricky to distinguish when the call is a method call and when it is not:

'use strict';
obj.printX();            // 42 - method call
(obj.printX)();          // 42 - method call
(false || obj).printX(); // 42 - still method call
(false || obj.printX)(); // Cannot read property 'x' of undefined - free call

Dangerous behavior in default mode

If you forget to add 'use strict' in the beginning of your script, it will run in default, non-strict mode. In default mode, “this” is set to “global object” for free function calls. In web browsers, global object is window. If your code happens to modify a property whose name coincides with one of the window object’s properties, it can lead to rather spectacular results:

var obj = { 
    location: "right: 20px",
    setLocation(side, pixels) {
        this.location = side + " " + pixels + "px";
    }
}

function goLeft(setter) {
    setter("left", 10);
}

goLeft(obj.setLocation); // oops...

When run in a browser (try it!), this code navigates to URL “Left%2010px”, because line 4 modifies window.location instead of obj.location. It is highly unlikely this was the intended behavior.

The exotic kludge of bind()

To get around the problem of undefined “this” for function expressions, JavaScript has a special function bind() that returns an “exotic function object” (it’s an actual term from the specification). When invoked, this object sets this to the value specified.

'use strict'
var obj = { 
    x:42, 
    printX() { console.log(this.x); } 
};

function invoke(action) { action(); }
invoke(obj.printX.bind(obj)); // 42

The trouble is, with “bind” you can set this to any value, sometimes with unexpected results:

'use strict'

var logger = {
    messages: [],
    log(text) {  this.messages.push(text); },
    out(level, text) { this.log(level.toUpperCase() + ": " + text); },
    clear() { console.log("Messages logged: " + this.messages.length); this.messages = []; }
};

function doStuff(out) {
    out("debug", "this is a test");
}

doStuff(logger.out.bind(logger));  // Logs to logger.messages
logger.clear();                    // Messages logged: 1

doStuff(logger.out.bind(console)); // Logs to console, bypasses logger.messages
logger.clear();                    // Messages logged: 0

doStuff(logger.out.bind(Math)); // Logs nowhere; attempts to calculate logarithm of some text
logger.clear();                 // Messages logged: 0

To be continued…

Originally published at www.ikriv.com. Please leave any comments there.

TL;DR

When building a Visual Studio solution on a build server, make sure that directory C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework contains reference assemblies for ALL .NET versions targeted by your projects. Exact match is required: project targeting .NET 4.5 cannot use reference assemblies from v4.5.1. You can obtain reference assemblies by installing “.NET Framework x.y.z Developer Pack”.

More details

I have just run into this problem: the solution would not build locally, because project A targeting .NET 4.5 was referencing project B targeting 4.6.1. The reference was ignored with a warning, and all attempts to use classes from project B led to compiler errors. Amazingly, the same commit compiled perfectly well on our build server.

I don’t like to leave such mysteries unresolved, because they to come back and bite you at the very worst moment. So I was compelled to investigate. Skipping the gore details of by arduous ordeal, here’s the takeaway:

1. We use TeamCity’s “Visual Studio (sln)” target, in combination with Microsoft Build Tools 2015.

2. When building a project targeting .NET version 4.x, it will look in C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.x for reference .NET assemblies. This includes mscorlib.dll, System.dll and other framework assemblies.

3. If it cannot find reference assemblies for that specific version, it will issue a warning and use assemblies from the GAC, which typically means the latest .NET version installed on the machine.

4. Installing specific version of .NET framework does not change the reference assemblies, but does change assemblies in the GAC.

5. You can install reference assemblies via something call “developer pack”, e.g. “.NET Framework 4.6.2 developer pack”. Technically, you only need a “targeting pack” for your specific version, but I could not find stand-alone installation for a targeting pack, it only seems to come as part of a developer pack.

6. Developer packs for .NET 4.5.2, 4.6.1, and 4.6.2 can be obtained from Microsoft Download center. I could not find anything for 4.5: it probably comes with Visual Studio 2013. I just copied files from my machine to the build server machine, and it worked.

My particular situation

Remember, I had project A targeting .NET v4.5 and referencing project B that targets .NET 4.6.1.

Step 1

The build server had .NET 4.5.2 installed, and reference assemblies for 4.5.1 and 4.5.2.
As a result, both project were built against GAC (i.e. 4.5.2) without errors, but with the following warning:

Project A:
warning MSB3644: The reference assemblies for framework ".NETFramework,Version=v4.5" were not found. To resolve this, install the SDK or Targeting Pack for this framework version or retarget your application to a version of the framework for which you have the SDK or Targeting Pack installed. Note that assemblies will be resolved from the Global Assembly Cache (GAC) and will be used in place of reference assemblies. Therefore your assembly may not be correctly targeted for the framework you intend.

Project B:
warning MSB3644: The reference assemblies for framework ".NETFramework,Version=v4.6.1" were not found...

Step 2

I installed .NET framework 4.6.1 – just the runtime, not the reference assemblies. Both projects are now built against 4.6.2, with no errors and the same warnings as in step 2.

Step 3

I installed .NET Framework 4.6.1 Developer Pack. This installs reference assemblies. Now project A is built against the GAC (4.6.1) with a warning, and project B is built without a warning.

Step 4

I copied reference assemblies for .NET 4.5 from my machine to the build server. Now project A is built against .NET 4.5 with an error:

warning MSB3274: The primary reference ProjectB.dll could not be resolved because it was built against the ".NETFramework,Version=v4.6.1" framework. This is a higher version than the currently targeted framework ".NETFramework,Version=v4.5".

Project B is built without errors. This is the behavior or was receiving on my local machine all along.

Conclusion

Do ensure that ALL .NET versions you use appear in the reference assemblies folder. Otherwise, some binaries you build may be not target .NET version they are supposed to target. Also, you may miss some .NET version mismatches in your projects.

Метки:

JavaScript WTF #4: undefined vs null

Originally published at www.ikriv.com. Please leave any comments there.

The forth place in the JavaScript WTF competition goes to the amazingly large number of ways to represent lack of value. Most C-like languages have keyword null that means “no value”. Beside null, JavaScript also has undefined, apparently meaning “like, totally no value”. The actual situation is even more complicated. A variable in JavaScript can be in any of the following states of no-value-ness:

  1. Not declared.
  2. Not initialized or explicitly set to undefined.
  3. Explicitly set to null.
  4. Temporarily dead (this is not a joke).

There is an impressive number of subtle differences between these states.

Not declared

In default, non-strict mode, not declared variables are treated as not initialized, and have implicit value of undefined. In strict mode, accessing a not declared variable causes a ReferenceError, except when used with typeof.

'use strict';
console.log(typeof notDeclared==="undefined"); // prints true
console.log(notDeclared===undefined);          // ReferenceError

Note that typeof notDeclared returns string "undefined", which is different from undefined value.

Not initialized

Declared, but not initialized variables are implicitly assigned a value of undefined. There is no way to distinguish between a variable that was never initialized, and a variable that was explicitly set to undefined.

var notInitialized;
console.log(typeof notInitialized==="undefined"); // true
console.log(notInitialized===undefined);          // true

Null

Null is interpreted as pointing to no object. It is different from undefined in a number of ways:

var nullVar = null;

console.log(typeof nullVar === "object"); // true
console.log(nullVar === null);            // true
console.log(nullVar === undefined);       // false
console.log(nullVar == undefined);        // true
console.log(1+null);                      // 1
console.log(1+undefined);                 // NaN

An attempt to access any property of null or undefined leads to ReferenceError. One can check for null or undefined in one shot using equality operator “==”:

if (someVar == null) ... // true if someVar is undefined or null

However, simply writing if (!someVar) is not recommended: the condition will be true not only for null and undefined, but also for false, the number 0, the empty string "" and Number.NaN.

Dead

Temporarily dead variables are an addition of EcmaScript6: these are variables declared via let or const keywords in the lines preceding their declaration:

function foo() {
   // x is in a "temporarily dead zone" (TDZ) here
   let x; 
   // x has value of undefined here
}

“Normal” variables are “hoisted” to the top of their scope, but “let” and “const” variables are not. Any access to a let or const variable prior to its declaration is not allowed. This includes the typeof operator.

console.log(declaredLater===undefined);        // true
console.log(typeof notDeclared==="undefined"); // true
console.log(typeof dead);                      // ReferenceError
var declaredLater = 42;
let dead;

Conclusion

To be fair, there are situations when it helps to distinguish “a value of null” and “no value at all”. E.g. when sending partial updates, null may mean “replace this field with null” and undefined may mean “do not touch”. When dealing with default function parameters: undefined means “use default value”, and null means “use null”. In the old days of COM we had VT_NULL, VT_EMPTY, and also vtMissing, which actually is a third, different value.

Still, JavaScript situation is a mess. The differences between the four “no-value” states are not intuitive, to put it mildly, and there are no explicit checks for them. I wish we had something like isDeclared(symbol), and isInTdz(symbol), but alas: the best we can do is to rely on confusing side-effects. Hence, the WTF.

JavaScript WTF #5: no map() for iterables

Originally published at www.ikriv.com. Please leave any comments there.

In the last few days I did some formal reading and informal experimenting with EcmaScript6, and compiled the list of its most annoying “features”.

The fifth place goes to complete lack of standard functions for iterables. EcmaScript 6 introduces a lot of cool stuff, but it brings a fair share of new WTFs, and adds new thrill to some existing ones. ES6 defines the concept of iterable and the for..of loop. You can now write something like this:

// iterable
function *range(start, len) {
    for (var i=start; i<start+len; ++i) yield i;
}

for (var n of range(3,4)) console.log(n); // prints 3 4 5 6 

Most languages that define iterables (a.k.a enumerables, sequences, comprehensions) come with standard methods that operate on them, such as map(), filter(), or groupBy(), but JavaScript has none. It does have map(), filter(), reduce(), but only for arrays:

var arr = Array.from(range(1,10));
console.log(arr);             // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
console.log(arr.map(n=>n*n)); // [ 1, 4, 9, 16, 25, 36, 49, 64, 81, 100 ]

console.log(...range(1,10));  // 1 2 3 4 5 6 7 8 9 10
console.log(...range(1,10).map(n=>n*n)); // error

Of course, one can define necessary functions with relative ease, but their omission from the standard is very annoying. Most articles on iterables simply ignore the subject. I found a library called wu.js that claims to implement them, but their ES6 download link is broken. There is also a library called functify. I also found comments from several people that said they tried to write a similar library and it was fun, but the result was horribly inefficient. If this is indeed the case, it makes iterables virtually useless.

The Procrustean bed of Resharper formatting

Originally published at www.ikriv.com. Please leave any comments there.

I was playing with some Javascript in Visual Studio, and I found that it gets annoyingly reformatted every time I end a statement or a block. Visual Studio formatting options have a choice of disabling auto-format, but Resharper is not that generous. All I get to choose is how the code will be auto-formatted, but there is no option to leave the formatting alone. This applies to any language, not just Javacsript.

E.g., consider this piece of code:

return (sorted[len/2-1] + sorted[len/2]) / 2;

I like it the way it is, but with Resharper the only options I get is no spaces around binary operators, i.e.

return (sorted[len/2-1]+sorted[len/2])/2;

or spaces around every binary operator:

return (sorted[len / 2 - 1] + sorted[len / 2]) / 2;

I like neither: the first one is too terse, the second one is too sparse, but that’s the only two choices I get if Resharper is installed. Quick googling reveals that ‘leave my code alone’ option has been requested several times in the past, but JetBrains insists that uniform formatting is good for your health. This thread is a typical example:

User: I have my assignments neatly formatted and don’t want Resharper to ruin it.
JetBrains: The main problem with such formatting style is that it is EXTEMELY hard to maintain

That is, they decided that they know better how to format your code, and you all you can do is to pick a party line and stick to it. Fooling around is not allowed.

Метки:

Originally published at www.ikriv.com. Please leave any comments there.

I was installing some web stuff using npm, and noticed that it takes a lot of time on my home computer compared to my work computer. It turned out that the main culprit is Windows Defender: the same package took 4 minutes to install with Windows Defender off, and 15 minutes with Windows Defender on. This is a big difference: those minutes do add app and eat your productivity. I replaced Windows Defender with eSet Nod32 Antivirus and now the install time is back down to 4 minutes.

I’ve been using eSet NOD32 for about 10 years now. From experience I found that major antiviruses like McAfee and Norton tend to slow down the PC a lot, while eSet is lightweight and fast, and catches viruses just as well. The good old eSet still got it, while Windows Defender joins the ranks of inefficient slow antiviruses. To be fair, unlike its famous cousins, Windows Defender is free, so you get what you are paying for.

The package in question was yeoman’s ng2-webpack generator for Angular 2 apps. After installing npm and yeoman, run the command is yo ng2-webpack.

My hard drive is SSD, so I would expect fast performance, but alas. This generator downloads tons of small modules from the Internet and produces a rather large package with over nine thousand 24,000 files and about 9,000 directories. It is no wonder that a slow antivirus solution triples the installation time.

PS. Surprisingly, disk indexer does not have much influence on the outcome: the time with and without indexer is about the same.

Javascript arrow function WTF

Originally published at www.ikriv.com. Please leave any comments there.

I thought that JavaScript arrow functions are just a shorthand notation for regular functions. I was wrong, and I found it the hard way. Arrow function treat ‘this’ keyword differently.

var x = 3, y = 4;
var obj = { 
  x: 42, 
  y: 50, 
  length1: function() { return Math.sqrt(this.x*this.x+this.y*this.y); }, // this === obj
  length2: () =>               Math.sqrt(this.x*this.x+this.y*this.y),    // this === global
};

console.log('length1: ' + obj.length1());
console.log('length2: ' + obj.length2());

They explain it by stating that separate ‘this’ scope for callback functions was getting in the way, so they got rid of it for arrow functions. RTFM, RTFM, and once more RTFM.

Apache: how to properly secure a folder

Originally published at www.ikriv.com. Please leave any comments there.

Here’s the scenario: the folder named “secure” contains sensitive data and should be protected by user name and password. To redirect all HTTP requests to HTTPS and enforce basic authentication for the folder, add the following to httpd.conf (etc/apache2/sites-enabled/000-default.conf on Ubuntu):

Read the rest of this entry »

КДПВ, courtesy of XKCD:

facebook_early

При попытке погуглить насчет режимов аутентификации в Апаче наткнулся вот на такое:

https://code.google.com/archive/p/mod-auth-external/
mod_auth_external has moved (and Jan Wolter has died and is no longer maintaining it).

Еще в 90-е Интернет был делом молодых - встретить такое сообщение можно было нечасто. Теперь же это в порядке вещей. Многих из первого поколения корифеев уже нет с нами: Дейкстра, Никлаус Вирт, Джон Постель, Деннис Ритчи... Да и Кнут с Керниганом далеко не мальчики. Это в математике и физике мы привыкли, что это наука мертвых - почти все, кого мы проходим в школе и на первых курсах института, умерли несколько сотен лет назад. Программирование до недавного времени было делом живых. Но, как говорится, post iucundam iuventutem, post molestam senectutem nos habebit humus.

666

Originally published at www.ikriv.com. Please leave any comments there.

Just found this in production code:

var fa = new FileAsset
{
    Hash = tempFile.Hash,
    Length = tempFile.Length,
    CreatedOn = DateTime.UtcNow,
    Data = tempFile.Data,
    CompressedLength = tempFile.Length,
    Name = tempFile.FileName,
    CompressionScheme = CompressionSchemeType.None,
    CreatedBy = 666
};

So, some unsuspecting user whose Id happens to be 666 is now the owner of all those files. His name is Ashour, by the way. I guess this number was entered as a stub since it was not obvious for the author how to get the ID of current user, and then was forgotten and made its way to production. Needless to say, this code has zero unit tests.

Profile

Веселый носорог
yatur
Yaturkenzhensirhiv - a handheld spy
Website

Latest Month

Февраль 2017
Вс Пн Вт Ср Чт Пт Сб
   1234
567891011
12131415161718
19202122232425
262728    

Syndicate

RSS Atom
Разработано LiveJournal.com
Designed by chasethestars