Category Archives: Uncategorized

The answer to the first-grader problem

The unknown numbers are, of course, 6, 5 and 3. What’s the difference between them? Well, you can’t find the difference between three numbers. You can find the difference between the unknown numbers on the right side, though. So you do just that and get 2. That’s another unknown number we found out. Now just find the difference between 6 and 2. The final answer is 4. Makes sense? What, it doesn’t? I agree. Figures.

Find the difference between the unknown numbers

This is a really stupid problem for Russian first-graders (7 years old or so). Given the picture below, find the difference between the unknown numbers. That’s it, really. I’m not joking.

Find the difference between the unknown numbers

Hints:

  1. The difference means...

    “The difference” means you have to subtract something from something. Answers like “the difference is that there is one unknown number to the left and two to the right” sound OK, but unfortunately are wrong.

    [collapse]
  2. The unknown numbers are...

    If you think that the unknown numbers are 6, 5 and 3, you’re correct. But how on earth do you find the difference between three numbers?

    [collapse]
  3. Almost the answer

    Don’t forget that this problem is for 7 year olds and it’s all about subtraction.

    [collapse]

MVC, MVP and MVVM, pt. 1: The Ideas

There is a lot of confusion going on about GUI design patterns such as Model–View–Controller, Model–View–Presenter and Model–View–View Model. I’m starting this series of blog posts to share my own knowledge and experience with these patterns, hoping to clear up things a bit. I’m not going to dive deep into the history behind these patterns. Instead, I’m going to concentrate on things as they are today.

I’ll start with the ideas behind these patterns. There is one single idea behind them all: separation of concerns. It’s a well-known idiom, closely related to the single responsibility principle, the S part of the SOLID principles. The most clear form of it says: there should be only one reason for a class to change. Separation of concerns takes that to the architecture level: there should be only one reason for a layer to change. The granularity of that reason is different, though. One may say: the Money class should only change if the logic of working with money changes. On the architecture level one would say instead: the view layer should only change when appearance should change (for example, money should now be displayed using a fixed-width font). In particular, the view layer should not change if the business logic changes (money should now be calculated to 2nd digit after the decimal point) or if presentation logic changes (money should now be formatted with 1 digit after the decimal point).

Model–View–Controller

With these ideas in mind, let’s go over the three patterns, starting with MVC. It’s probably the most confusing of them all, and I think it’s mainly because separation of concerns is not complete in MVC.

mvc

To add to the confusion, there are many variations of MVC, and there is no single agreement on what exactly the components do. The view is the easiest part: its job is to display things and receive interactions from the user. You can’t really separate these two concerns: how would you separate displaying text that the user is editing and actually editing this text? There should be a single graphical component that does both of these things. You can do the next best thing, though: delegate user interactions to another component. And here is where the controller comes from.

The controller receives user interactions from the view and processes them. Depending on the interface between the view and the controller you may be able to reduce coupling between them, and that’s a good thing. Suppose your view is implemented with Swing, and there is the apply button. Instead of making the controller implement ActionListener, implement it inside the view and delegate the apply button click to the apply method of the controller, which is UI-agnostic (it doesn’t depend on Swing at all).

That was the easy part. But what happens next? The controller acts on the model, which contains the actual data the application works with. Then, at some point, it may be needed to display the updated data back to the user. Here is where the confusion starts. One possibility is that there is the observer pattern acting between the view and the model. In this case, the view subscribes to certain events of the model, and the model either sends the updated data to the view (the push model of the observer pattern) or just events (the pull model). In the latter case, the view needs to pull the necessary data whenever it receives the appropriate event.

Note that even though the model sends data to the view, it has no idea of its existence because of the observer pattern. This is especially important if the model is in fact the domain model, which should be isolated as much as possible. It should only communicate to the outside world through clean interfaces that belong to the model itself.

Another variation of the MVC pattern is often seen in web frameworks, such as Spring MVC. In this case, the model is a simple DTO (data transfer object), basically a hash map, easily serialized into JSON or something. The controller prepares the model and sends it to the view. Sometimes it’s just a matter of passing the object inside a single process, but sometimes the model is literally sent over the wire. This is different from a typical desktop observer approach where the controller doesn’t even know anything about the view. To keep this coupling loose, the controller often doesn’t send the model directly to the view, but rather sends it to the framework which then picks up an appropriate view and passes the model to it.

web_mvc

What makes this pattern especially confusing is that the model is no longer the domain model. Rather we have two models now: the M part of the MVC pattern is the data transfer model, whereas the controller acts on the domain model (maybe indirectly through a service layer), gets back the updated data, then packs that data into a DTO and passes it to the view to display. This very idea of the data transfer model is exactly what makes this pattern so suitable for web applications, where the controller may not even know in the advance what to do with the data: you may have to wrap it into HTML and send to the browser, or maybe you serialize it into JSON and send it as a REST response.

Either way, one problem with MVC is that view is too complicated. One thing about UI is that it tends to be both heavyweight and volatile, so you usually want to keep it as clean as possible. In MVC, view doesn’t only display data but it also has the responsibility of pulling that data from the model. That means the view has two reasons to change: either requirements for displaying data are changed or the representation of that data is changed. If the model is the domain model, then it’s especially bad: the UI should not depend on how data is organized in the domain model. If the model is a DTO model, then it’s not that bad, but it still can be changed, for example, to accommodate the need for a new view (or a REST client). Still, MVC is often the best choice for web applications, and therefore is the primary pattern of many web frameworks.

One major disadvantage of MVC is that the view is not completely devoid of logic, and therefore it can be hard to test, especially when it comes to unit tests. Another disadvantage is that you have to reimplement all that logic if you’re porting your view to another tech (say, Swing to JavaFX).

Model–View–Presenter

One natural way to improve MVC is to reduce the coupling between the view and the model. If we make a rule that all interactions between the view and the model must go through the controller, then the controller becomes the single point for implementing presentation logic. That’s what we call a presenter. The term presentation logic refers to any kind of logic that is directly related to the UI but not to the way how the components actually look (that’s the view’s responsibility). For example, we may have a rule that if a certain value exceeds a certain threshold, then it should be displayed in red color. We split this rule into three parts:

  1. If a value exceeds a certain threshold, then it’s too high.
  2. If it’s too high, then it should be displayed in a special way.
  3. If it’s too high, then it should be displayed in red.

The first part is the domain logic. It could be implemented, say, with an isTooHigh method, but it really depends on the domain. The second part is the presentation logic, and if it looks like a generalization of the third part, that’s exactly what it is. The presenter knows from the model that the value is too high, and therefore, passes it to the view with some kind of Status.TOO_HIGH enum constant. Note that it has no idea of colors yet. It’s the job of the view to actually map that constant to a color. Or maybe it could be something else than a color, like a warning sign next to the value.

mvp

In the MVP pattern, the view is completely decoupled from the model. The presenter is something similar to the mediator pattern. In fact, if the view is implemented as a set of independent graphical components (like multiple windows), and the model also consists of multiple objects (as it almost always the case), it would be exactly the mediator pattern.

Unlike MVC, there is no observer pattern between the presenter and the view. The reason for this is that the view contains so little logic there is no place for any event handling there, except for view-specific UI events (button clicks etc.). It’s the presenter’s job to figure out when to update the view and do so by calling appropriate methods. These methods typically belong to an interface fully defined by the presenter, which is an excellent example of the dependency inversion principle (the D in SOLID). The presenter doesn’t depend on any technologies the view uses. Well, in theory at least. For example, it would be very tricky to implement exactly the same interface with Swing, JavaFX and HTML. How do you call methods on HTML? You could have some server-side object that sends the data to the browser using AJAX or even Web Socket, I suppose, but it would be very tricky and at the same time not as powerful as MVC, where controller is free of presentation logic and therefore can be shared between views with different presentation needs (such as HTML and JSON).

The positive side is that since all presentation logic is in one place, porting to another view tech is a breeze. You just reimplement your view interface with another tech, and you got it. Well, that’s at least in theory. In practice you may run into various problems. Threading, for example. Who is responsible that view methods are only called in the appropriate threads? Should the view enforce that? Probably yes, because the presenter has no way of figuring out which thread is right if it has no idea what GUI framework is used in the first place. But that imposes additional burden on the view. But still, MVP is probably as close as you can get to the perfection of total independence from the GUI framework used.

The bad news is that presenter now contains a lot of boilerplate code. It was a part of the view before, so it’s not like it became any worse than it was with MVC, but still it’s always a nice idea to get rid of as much boilerplate code as possible. That’s where MVVM comes into the picture.

Model–View–View Model

mvvm

MVVM is basically the same thing as MVP, except for one major difference. In MVP, the view only delegates user interactions to the presenter. Whenever the feedback is needed, it’s the presenter who takes action. It does it by literally calling methods on the view such as displayFilesList(files), setApplyEnabled(true), setConnectionStatus(ConnectionStatus.GOOD) and so on. That’s boilerplate code. With MVVM, the presenter becomes the view model, that is, a model that provides access to the ready-to-display data through the observer pattern, much like in desktop MVC. Except that now the view model can really prepare that data for display by filtering, sorting, formatting etc. So whatever presentation logic was in the view in MVC, it’s now in the view model. And while in MVP the presenter pushed that data from to the view, in MVVM the view pulls that data from the view model. This sounds like we’re adding responsibility to the view, and that’s a Bad Thing, right? Well, to a certain extent, yes. But the point is, this responsibility is typically almost entirely implemented by the framework. This is done through data binding, where you just specify that this component should display that property of the view model, and that’s basically it.

When your framework doesn’t support data binding, it’s usually a bad idea to use MVVM because you’ll essentially be moving the boilerplate code from the presenter to the view, which is indeed a Bad Thing. And even if you have data binding, it’s usually not that simple. Sometimes you have complicated structures to bind. Sometimes the order of updates is important and you have race conditions in your UI. Sometimes you have values of custom types that are tricky to display directly, you need to employ some sort of converters for that.

The good part is that with MVVM you typically only have problems when you have a non-standard situation. For most cases, it really decreases the amount of boilerplate code and displaying a person’s name in a text field becomes as simple as writing Text=”{Binding Person.Name}” in XAML.

Moreover, delegating user interactions is often implemented with data binding too. Well, as I say “often”, I really can’t think of any other MVVM implementation than .Net/WPF, so I guess it’s 100% of all cases, even though there is only one case in total! Nevertheless, using the command pattern, we can expose possible interactions as properties of the view model. The view then binds to them and executes appropriate commands when the user does something. One big advantage of it is that we can easily change these commands dynamically and the view will automatically update its interactions.

When choosing between MVVM and MVP, it’s important to consider several factors:

  • If your framework doesn’t support data binding, MVVM is probably a bad idea.
  • If it does, then how likely that you’ll want to switch UIs? How painful is it likely to be?
  • How difficult it would be to port your application from MVVM to MVP or MVC or vice versa?

All things being equal, it’s often the case that reimplementing the view interface for a new framework in MVP pattern is about as hard as switching from MVVM to MVP or whatever. In this case, it’s probably worth to use MVVM if that’s the thing with your framework. The same really goes about using MVC. When your framework offers you MVC, you probably don’t want to force yourself to use MVP instead unless you really plan to switch frameworks and design for it beforehand. Say, you’re using Swing right now, but you know you’ll have to move to JavaFX within 5 years.

One last thing to note is that it is possible to combine these patterns, although in most cases it’s likely to lead to over-engineering. For example, if your framework forces you to use MVC, you can really turn your controller into a view model, and then consider the whole view–view model part to be just a view for the MVP pattern. So when user does something, the view delegates that to the controller, which immediately delegates to the presenter. When the presenter gets updated data from the domain model, it sends that data to the controller (using a clean interface), which then stores it locally and fires an event to the actual view which pulls that data to actually display it. Sounds crazy enough as it is, doesn’t it? But sometimes it may be worth it, only experience can tell you. It’s probably best to start with the simplest thing possible, and complicate things only when you actually need it.

That’s it for now. I plan later to demonstrate all three patterns with a simple application. I’ll probably use Java for that, even though implementing MVVM would be tricky. But there is some limited data binding in Java, so it could actually work, if only for demonstration purposes.

How to write a web book in XXI century

It all started because I wasn't feeling well and had to stay at home for a few days. But since it can be pretty boring, I decided to sort out my limited knowledge of Hebrew by putting it into a kind of a web book or something like that. Maybe, just maybe, if I really learn Hebrew someday, it will turn into a nice language course for nerds like me. And if I just get bored of it before I actually finish, then I'll at least waste enough time doing it so I won't be bored for a while. It's a win-win idea.

One would think that writing a web book is something that is easily done in XXI century, provided, of course, that you know what to actually write there. I mean, there is Unicode, there is appropriate markup for bi-directional text in HTML, and it seems to be well supported by the mainstream browsers. Just pick up the right tools and write! Or so I thought.

The first issue is to find the right format. Writing directly in HTML isn't the best idea (although it can be done too) because HTML lacks internal structure. You'll have to struggle with chapter numbering, table of contents and splitting the thing into the right number of HTML pages. HTML is the best output format for web publishing, but it's not quite right to actually write in it.

The first format I thought of was Lyx, as its WYSIWYM (what you see is what you mean) idiom gives the most content with the least effort required to format everything. I already used it for my "Endgame: Singularity" Impossible Guide and found it quite nice, especially when there is math involved. I knew there were some problems with Unicode support in TeX/LaTeX, but I thought that such a nice piece of mature software should have all those solved already… Boy, was I wrong!

There is a whole bunch of UTF-8 encodings, using XeTeX or whatever-TeX, but none of them seemed to actually work. After struggling with it for a while, I realized that using TeX in any way cripples the very idea of using Unicode to get rid of all multi-language troubles even before they appear.

OK, so I thought I needed some decent format with native support of Unicode. Something like XML. Of course, raw XML is kind of useless unless I wanted to write my own XSLT sheet, which I didn't. So what I needed was an XML-based format that is designed for writing structured documents… Looks like Docbook is the way to go! It is designed for technical documentation primarily, but nothing stops from using it for anything else, as long as nothing special is required of it, and my requirements were quite simple indeed.

Now the only thing that I needed was a sort of WYSIWYG/WYSIWYM XML editor with Docbook support because I didn't want to write raw XML with Vim or something like that. Given Docbook's popularity, there must be plenty of them, right?
The horror story

Don’t set clock to match local time zone!

There are rumors that Russian time zones are going to change yet again. Hopefully we'll get rid of daylight time once and for all. This made me think of people who set their clocks to match new time zone each time they discover that their clock on a PC or a phone shows wrong time. Well, don't do it!

Setting a clock to match the new time zone works fine for mechanical clocks and primitive electronic clocks. So why is it so wrong to do the same thing with a computer or a phone? Because almost any such device runs its clock in UTC. That is, Greenwich time with no daylight corrections whatsoever.

Hey, but I don't see Greenwich time on my clock! I see the right time for my area!

That's right, if you live, say, in Houston, your clock will show (at summer) 8 AM when it's 1 PM UTC in the internal clock of your OS. Why? The answer is time zones.

Before displaying the time, your computer converts it to the local time zone. That's why you have to choose it when you set up your OS. So at any given time your OS knows two things: what's UTC time right now and how it differs from the local time. This makes all internal time processing incredibly simple: the OS doesn't have to take time zones into account. If it has two times, it always knows which one is later, and what's the exact difference is – it just has to subtract one time from another.

Now suppose your local authorities decide to change time zones in your area, like they wont to do it in Russia lately. Say, Texas decides that it no longer needs daylight time, so 8 AM becomes 7 AM now. But your clock still shows 8 AM, so you just go and set it to 7 AM. You now see the "correct" time, but then all kinds of strange things begin to happen. Mail shows wrong time, internet forums show wrong time, files on USB sticks have incorrect time stamps, and sometimes antivirus gives you vague alerts which not only you don't understand, but you get the feeling that the antivirus itself doesn't quite figure out what it doesn't like.

So what's wrong with just setting the clock to match the new time?

The reason all this crazy stuff is happening is because you didn't actually change 8 AM to 7 AM. While you might think you did something like this:

8 AM => 7 AM,

you actually did it like this:

8 AM CDT => 7 AM CDT = 6 AM CST

or, actually,

1 PM UTC => 12 PM UTC,

which is the same thing. Now when a mail arrives, your OS knows its time and its timezone, converts it to UTC, and then to your local time zone. Say, I wrote an e-mail to a guy in Texas. I am not too far away from Moscow, so my time is 5 PM MSK which is 1 PM UTC, which is 8 AM CDT or 7 AM CST. Now that guy has the time set to 6 AM CST, so here's what his OS thinks: "OK, so there's this mail that was written at 17:00 UTC+4, which is not a very convenient way to write it, so it would be much better for me to represent it as 13:00 UTC, but then again, while it's perfect for me, it's not the best way for my user, so I better convert it to the local time zone, which would be, well, let me think… 08:00 CDT (UTC-5). But wait! What's that? That's one hour into the future! Oh, that must be a junk mail or some sort of virus! I better warn my user!"

OK, what is the right way to do it then?

What you really need to do is not to fix the time, but to fix the time zone. Unfortunately, this is made incredibly hard for some reason. You can't just say, well, let's just set the time zone to UTC+4 and change it to UTC+3 at 03:00 AM on the last October Sunday. At best, you can just change it to UTC+4 or UTC+3, but then you have to adjust it manually unless your local authorities abolish daylight adjustments altogether. But even this strategy only works on some phones, and doesn't work in Windows 7, for example. It just lets you choose from a huge list with various places.

So what can be done if the OS on my PC or in my phone doesn't let me to set the right zone?

There are three ways.

The first way is to update the OS, hoping that developers already incorporated the new time zone rules. This has a nice effect of OS always showing the correct time, even for dates far in the past, because it actually remembers what all those rules were like long ago. This is actually the best way, and it can be as simple as just running Windows Update, or as hard as having to upload new firmware into your phone. In the worst case, you could be using an OS that is so outdated that no updates are available.

Here comes the second way. A geeky way. If there are no updates, you can make it yourself. It can involve registry edits or some really bizarre tricks like hex editing your phone's firmware. Someone could have done it for you already, so you may want to look for a ready recipe in the Internet. But there's an even easier way.

The third way is to just find a timezone identical to what you need. You need to switch to UTC+4, but your old OS doesn't know that Moscow is there already? Just choose Yerevan or whatever! Just don't forget to turn off daylight savings or you'll be in for a huge surprise – Yerevan's rules for daylight adjustments might not be exactly what you need. This has a disadvantage is that times in the past will probably be wrong because you now applied the whole history of that foreign place to your system's time zone rules. But at least the present will be present.

Reverse stereo – hardware solution

It all started when I decided to replay the Thief series games. Having finished Gold and Metal Age, I went on to Deadly Shadows, but then suddenly noticed one terrible thing: there is no option to reverse stereo in Deadly Shadows. Well, technically, there are three options in the config file, but neither of them is working. Well, it's the third game in the series, it must be worse than previous two, right? At least they didn't make it as bad as Doom 3 or Fallout 3.

So I thought, hey, it's just a matter of swapping stereo channels, right? There ought to be something like that in the driver settings or in Windows 7 control panel, or registry or somewhere! As it turned out, Windows used some built-in drivers for my on-board Realtek HD Audio card, and Windows 7 itself doesn't have the "reverse stereo" option. Well then, I must install Realtek drivers and there I'll find what I need. Or so I thought.

After installing Realtek drivers, I ended up with some crappy Manager in my tray, which had ridiculously many settings, including type of material that walls in my room is made of. But no "reverse stereo" option, of course. I should've guessed. There is no way hardware manufacturer will provide anything useful in their software except maybe drivers. If it was Linux, I know I could've done it with some ALSA settings, but I just didn't want to install Linux just to play a single Windows game, even though it's supposed to run there with no problems.

Now stupid people (or people assuming that I'm stupid) would say, "Hey, how about just moving your speakers?" Duh! If it was so easy, I would've done it when I was placing them there in the first place. The reason I couldn't do it was that the AC cable is too short to reach the place where the right speaker is, so I just had to place it on the left side. And no, using an AC extension cord is not an option: I don't want to increase the number of 220V cables and plugs around my PC more than I have to.
The solution

Мемшала

Итак, Биби всё-таки что-то собрал из букв А, Ж, О и П. Никто не знает пока, вышло ли у него слово "счастье", но сам факт уже удивляет. После того, как Лапид объединился с упоротым Беннетом, я уж думал у него точно ничего не выйдет.

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

Впрочем, я всё равно не могу себе представить слаженную работу такой мемшалы. БАГАЦ постановит снести какой-нибудь сарай где-нибудь в Иудее, Беннет обидится и демонстративно выйдет из коалиции. И кто вместо него придёт? Харедим?

Продолжаем битву с HTML5 local storage

Итак, HTML5 local storage при ближайшем рассмотрении оказался файлом webappsstore.sqlite в профиле Firefox. К счастью, они не стали изобретать велосипед, а воспользовались стандартной БД SQLite, для которой полно приложений, в том числе есть даже плагин под FF, хотя в чём смысл плагина, работающего с локальными файлами по сути независимо от браузера, мне не слишком понятно. Но зато теперь можно сделать, например, вот такой запрос:

SELECT * FROM webappsstore2 WHERE key = ‘placeholders’;

И получить примерно следующее:

scope key value secure owner
moc.lanruojevil.oaya.:http:80 placeholders {“http://s42.radikal.ru/i097/1302/04/b553dec9adc2t.jpg”:true} 0

Что означают последние два столбца, я так и не понял, но особо не разбирался. С key и value всё ясно. Ну а первый столбец – это цирк какой-то. С http:80 всё ясно, а вот moc.lanruojevil.oaya – это, ясен пень, ayao.livejournal.com. Зачем это сделано – не совсем ясно, но вроде есть какие-то намёки на то, что это упрощает работу со строками. Например, можно удалить всё с livejournal:

DELETE FROM webappsstore2 WHERE scope LIKE ‘moc.lanruojevil.%’;

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

Image placeholders или fuck HTML5 storage

Итак, дано: ЖЖ, френдлента, в ней – картинки, настолько большие, что на монитор не помещаются. Результат – нечитаемая френдлента. Найти: как с этим бороться?

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

Решение второе, техническое. Включаем в настройках ЖЖ image placeholders. Теперь все картинки стали маленькими кнопками. Нужна картинка – нажимаем кнопку. Не нужна – не нажимаем. Победа? Как бы не так. Этот механизм делал то ли сатанист, то ли садист, то ли просто нормальный человек. Так или иначе, если картинку один раз загрузить, больше вы от неё не избавитесь. Что делать?

Соображение первое. Если картинка не нужна, то её загружать не следует. Как понять, нужна она или нет, если размер и содержимое неизвестны заранее? Оказывается, очень просто. Placeholder является не только кнопкой, но и ссылкой. Если открыть её в отдельной вкладке, то просто открывается оригинал картинки – placeholder при этом остаётся на месте, не заменяясь картинкой.

Казалось бы, задача решена. Но возникает вопрос – а что делать, если нечаянно кликнули на placeholder? Как-то же убрать картинку обратно можно? Наблюдения: очистка кукисов livejournal.com не помогает. Смена браузера – помогает, стало быть эта информация не хранится на сервере. Не в кукисах, не на сервере, так где же, блин?

Позвольте вам представить новую технологию HTML5 – local storage! Теперь у веб-разработчиков есть ещё один способ причинять страдания пользователям. Я-то по наивности думал, что все подобные технологии были порождены сумбуром зари веб-технологий… Ни фига, принцип остался тот же – лишь бы навредить. Разработчики браузера, естественно, в сговоре с террористами – функции "удалить на Хрен local storage" в Firefox нет. Разработчики плагинов, похоже, тоже в доле – есть плагины для просмотра содержимого local storage (и проклятые placeholders там очень хорошо видны), но удалять они не умеют. Но один всё-таки нашёлся: ClearConsole. Правда, удаляет он всё без исключения – удалить только placeholders или хотя бы только local storage ЖЖ невозможно, это вам не кукисы. Ну ничего, пользы от этого local storage всё равно нет, поэтому можно смело удалять всё. Победа разума над интеллектом!

Яндекс.Карты и NoScript

Задолбался ковыряться с Яндекс.Картами. Не работают панорамы – хоть ты тресни. В IE работают, в FF – нет. Стал отключать плагины – оказалось, дело в NoScript. Переключился на другой профиль – там оно почему-то работает, хотя NoScript тоже установлен. И тут меня осенило, что там версия NoScript допотопная. Стал искать, с какой версии это началось. Оказалось, с 2.5.8. Откатился было к 2.5.7, но вроде как-то нехорошо это. Решил бы написать багрепорт, а там написано – надо предоставить все сообщения с консоли ошибок JavaScript. Стал там копаться, а на вкладке "Messages" NoScript что-то ругается про скрипт с некорректным типом, включаемый Яндексом…

Короче, выяснилось, что в Яндексе какой-то скрипт имеет тип application/octet-stream, что для скрипта, мягко говоря, странно. NoScript это невзлюбил и заблокировал (не смотря на то, что Яндекс в белом списке). К счастью, для таких извращений нашёлся свой белый список в about:config под именем noscript.inclusionTypeChecking.exceptions – добавил yandex.st (через пробел) в конец, всё стало работать и в последней версии NoScript.