singalen: (Default)
Рассматриваю чудесный баг с функциональным стилем и ленивыми вычислениями, но в присутствии сайд-эффектов.

Передаётся в функцию лениво-вычисляемая коллекция "where", скажем, зайцев. В коллекции записано, каких зайцев, допустим, нарисовать.
Функция их рисует и взводит каждому флажок "нарисован".
Естественно, изначально в условии where стоит "не нарисован".

А потом нужно, скажем, освежить их в кэше. Вот мы и проходимся ещё раз по коллекции - и оппа! Правильно, она пустая, зайцев нет, кэш не обновляется. Или ещё хуже - зайцы с флажками, взведёнными из другого потока.
И под дебаггером она, гадость, не смотрится, потому что yield return не вычислен.

Вот вам и функциональный стиль в императивных языках.
Tags:
singalen: (Default)

Originally published at Fiberglass flowers. You can comment here or there.

Another problem with MSBuild bootstrappers that can screw all your installation

If scheduling reboot after installing .NET or other prerequisites, bootstrapper copies itself to run from TEMP on boot. Why not staying where it is - who knows. And definitely, all the other MSIs are not copied, so it won’t find them. Reproduced for me.

Now give up and go write own bootstrapper. I’m setiously considering going for InnoSetup deployment.

For now, I’m trying a crazy ting, to copy MSI to TEMP for Setup.exe to find it after reincarnation… It’s the way to use given tools.

Tags:
singalen: (Default)

Originally published at Fiberglass flowers. You can comment here or there.

Now I know it.

It’s Windows Installer error 1618 that I didn’t see somewhy when attempting to fix .NET bootstrapper. Either I was inattentive or it wasn’t there: “Another copy of msiexec is running”. You can’t have two Windows Installers running, at least if one of them installs .NET. Information is from this maillist post.

Why? Implementation limitations, I believe. No sane reasons for such a contract, no article mentioned this. Surely, who’s going to declare own “features” of that kind - just a gentle hints that “you should better use bootstrapper”. Another reason to long for a systems where setup is just a copy.

So go pack a MSI, then make a MSBuild bootstrapper.

Oh wait, do I have to have 2 files in my installation? And my customers can’t download one file?

Yes. Or go for WinZip Self-Extractor, or WinRar, or whatever else.

What about build scripts? For WinRar, here’s a nice sample. For WinZip sfx, there’s also a command-line interface. Do a

wzipse32 %ARC_NAME% -setup -auto -runasuser -le -i ../icon.ico -wait msiexec -c ".\setup.exe"

WinZip will do the thing, though displaying some dialogs we don’t need at all.

Oh, WinRar won’t work, because it erases temporary files upon setup.exe completion. And we need to wait for msiexec, because setup.exe exits earlier. What a pity.

Tags:
singalen: (Default)

Originally published at Fiberglass flowers. You can comment here or there.

After Microsoft didn’t include .NET 3.5 in any current release of Windows (read “Vista service pack 1″), some of us developers who believed in long-ago C# 3.0 ads, had to roll back to .NET 3.0 and C# 2.0.

Including me.

Not mentioning pain of rolling back all LINQ tasties in code and debugging our replacements (do you know why you can’t implement Where() just with yield-style function?), it means installing .NET 3.0.

It seemed to be not a problem, having a MSBuild code snippet that worked for 3.5 - just replace 3.5 with 3.0:

<ItemGroup>
<BootstrapperFile Include="Microsoft.Net.Framework.3.0">
<ProductName>.NET Framework 3.0</ProductName>
</BootstrapperFile>
<BootstrapperFile Include="Microsoft.Windows.Installer.3.1">
<ProductName>Windows Installer 3.1</ProductName>
</BootstrapperFile>

<Target Name="Bootstrapper">
<GenerateBootstrapper
ApplicationName="blah blah blah blah"
BootstrapperItems="@(BootstrapperFile)"
BootstrapperKeyFile=""
OutputPath="obj"
ComponentsLocation="HomeSite" CopyComponents="false"
SupportUrl="http://www.microsoft.com/downloads/details.aspx?familyid=10CC340B-F857-4A14-83F5-25634C3BF043"
Culture="en" Path="$(BootstrapperPath)"/>
</Target>

Won’t work.

Hell why? Who knows. Logs in temp don’t give proper diagnostics, nor system events do. WPF fails to install at some point onto every XP installations we have, including clean special test XP SP2 VMWare images downloaded from Microsoft.

Update: Here’s the answer.

Now I rolled back to dotnetfx3setup.exe redistributable. It’s 2.8M compared to 300K bootstrapper generated by MSBuild, and it’s a pain to see installer grow…And if .NET 3.0 is already installed it starts to uninstall it… and there is no key to make it just “check or install”, need to trick it via WiX.

But we have to pay it. Oh my.

All over the Web I see no evidence that any man walked this path before. For.NET 2.0 - a lot of mentions and code samples. And completely empty for .NET 3.0.

Tags:
singalen: (Default)

Originally published at Fiberglass flowers. You can comment here or there.

Some pages that somewhy didn’t appear at top of Google searches for WiX help.

Tags:
singalen: (Default)

Originally published at Fiberglass flowers. You can comment here or there.

Till now, I did understand but didn’t remember the very situation, as I wasn’t the one creating thread pools and alike: all the core things were already there.
It’s a blessing to work for start-up.
You can think about

Monitor.Wait(toRetrieve); // will throw SynchronizationLockException

Now, after a look into docs, I see that one needs to hold the monitored object lock to avoid race conditions: a thread wakes up already holding a lock for an object it needs. The thread that did Pulse() acquired that lock and safely passed it to Wait()ing one.
Just watch out for deadlocks: it’s easy to wake up with one object lock, try to acquire another and die then…

lock(toRetrieve)
{
  Monitor.Wait(toRetrieve); // will throw SynchronizationLockException
}

As Doug Lea recommends in his excellent eternal “Concurrent Programming in Java“, just make it impossible. Lock only on a single object. If you really really need two locks, make them ordered: always acquire A then B.

If you do:

lock(a){
  // :
  lock (b)
  {
    //:
  }
  // or:
  b.SomethingThatLocks();
}

//then will you never ever do

lock(b)
{
  //:
  a.SomethingThatMightLock();
}

as calling other objects’ methods while holding a lock badly affects your karma.

For more in-detail look, read “EventWaitHandle and Monitors: how to pick one?” by Joe Duffy. He goes very deep down to system details.
He also did a nice brief overview of missed pulse problem - why do you always check wait condition in a loop:

while (toRetrieve.Count == 0)
{
  lock(toRetrieve)
  {
    Monitor.Wait(toRetrieve);
  }
}
Tags:
singalen: (Default)

Originally published at Fiberglass flowers. You can comment here or there.

  • Why FindAll() is not in IList? IDictionary or at least Dictionary? Are you pushing me to code for implementation?
  • Why WeakReference, but no WeakDictionary (get a nice one from Nick Guerrera)? WeakList? More?
  • Why ReadonlyCollection<T>, but no ReadonlyDictionary<K, V>?
  • (I can live with this one) Why Array.Length, but anyCollection.Count (thank Nick Guerrera again)?

…more to follow as I recall them…

Tags:
singalen: (Default)

Originally published at Fiberglass flowers. You can comment here or there.

Am I the only one who ran into .NET (or GDI?) bug with Pen (or Matrix) .ScaleTransform()?
When I scale a pen to certain width, and it has an anchor, anchor draws at inverse scale.
I might be missing something, but here’s my test. Pen scales proportionally to form width, for simplicity.

Here’s how it looks:

You see, the thinner the line, the bigger is the cap. Uh-oh.

My workaround should be here after some time.
Source code for interested ones:

private void Form1_Load(object sender, EventArgs e)
        {
            pen.StartCap = LineCap.SquareAnchor;
            //pen.EndCap = LineCap.ArrowAnchor;
            pen.EndCap = LineCap.DiamondAnchor;
        }

        private readonly Pen pen = new Pen(Color.Black, 2);

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            pen.ResetTransform();
            float scale = Width / 300.0F;
            pen.ScaleTransform(scale, scale);
            e.Graphics.DrawLine(pen, 10, 10, ClientRectangle.Width - 10, ClientRectangle.Height - 10);
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            Invalidate();
        }
Tags:
singalen: (Default)

Originally published at Fiberglass flowers. You can comment here or there.

It was pretty strange for me to get a “CS0103: The name ‘AppliesToNode’ does not exist in the current context” from C# compiler for a code:

class Copyrighted : IBackend
{
  bool IBackend.AppliesToNode(string Uri)
  {
    return something;
  }
...
    if (!this.AppliesToNode(Uri)) { ...}

while (this as IBackend).AppliesToNode(PexUri) compiles.

  • On one hand, it’s pretty strange: Copyrighted IS a IBackend, why not accessig its public members? It breaks Liskov substitution principle in certain sense;
  • On other hand, separation of namespaces is good: it decreases coupling.

Later I found a following paraagraph in ECMA-334, item 20.4.1:
Explicit interface member implementations have different accessibility characteristics than other members. Because explicit interface member implementations are never accessible through a qualified interface member name in a method invocation or a property access, they are in a sense private. However, since they can be accessed through an interface instance, they are in a sense also public.
And even:
Because explicit interface member implementations are not accessible through class or struct instances, they allow interface implementations to be excluded from the public interface of a class or struct.
So this is even a primary aim of the explicit interface implementation: to EXCLUDE interface members from class signature. You will not be able to call these members on class-typed variable: only cast it to interface.
I take it as “static const” rule in C++: no good way to decide which way is better, so just take one of them.

Tags:
singalen: (Default)

Originally published at Fiberglass flowers. You can comment here or there.

Till two years ago, I didn’t know that C# 2.0 had closures (reference to Joe Walnes’ blog). Now declarative programming is slowly coming into fashion.
Reference taken from classicist. The latter has a bunch of short bliki-articles, all worth reading.

Please note variables visibility scope:

public List<Employee> HighPaid(List<Employee> emps) {

int threshold = 150;
return emps.FindAll(delegate(Employee e) {
return e.Salary > threshold;
});

}

interesting quotation about arguments against closures in Java - about memory allocation. Found again by Martin Fowler’s reference, in Guy Steele’s archive:
One of the early design principles of Java was that heap allocation occurs if and only if a construct involving the "new" keyword is executed. Adding full-blown closures violated this design principle. (Dynamic class loading also violated the principle, but users seemed to be comfortable with that, perhaps because they believed that "once the computation got going" no more heap allocation would occur.)
Other features for Java release 1.5 will perform certain kinds of autoboxing, which also violates the design principle. This fact will make it easier to argue for restoring full-blown support for closures in the future.

upd: But .NET doesn’t have an unordered container (set), and these cool Find()/FindAll() don’t exist in IList. Too bad.

Oh yes, and Python always had closures.

Tags:
singalen: (humpty-dumpty)
Написал для товарища тут письмецо, и подумал - чего контенту пропадать, вывешу.

Initial info about unit tests is good enough in two docs in NUnut distribution.
Martin Fowler's "Refactoring" gives some very good ideas.

Another useful technique is "Mock objects". Articles are:
http://www.mockobjects.com/
http://www-128.ibm.com/developerworks/library/j-mocktest.html
First article on this: http://www.connextra.com/aboutUs/mockobjects.pdf

Book to read to become a guru.

Software to use.
NUnit's been a de facto standard for couple of years:
MSVS plugin making it easier

MS VS 2005 now has own unit testing tool.
singalen: (2002)
Прочитал про "младшего брата" слова RTFM, STFW. Забавно. Кстати, чудесный текст.
Мне сказали, что корпоративные информсистемы на .NET пока что не особо успешны, и это из-за отсутствия хорошего аппсервера. Интересно, почему так? И зачем обязательно сервер приложений?
Не боясь показать чайниковую сущность, спрошу: почему вообще важен аппсервер? Скажем так: это же фреймворк. Если не делать inversion of control, а добиться тех же функций от библиотеки, скажем, персистенции от Hibernate-а-не-EJB, IPC от CORBA-а-не-SOAP, и так далее - то серверный процесс будет сам себе application server, вернее, сервером бизнес логики.
Пошёл учиться, учиться и учиться, как завещал Ленин. И делать STFW.
singalen: (hope_never)
Хочу плагин для Вижуала: рисовать диаграммы классов, можно не в самой IDE, и сохранять их в XML Comments.
А потом вставлять их же в NDoc. Т.е. плюс парный плагин для NDoc.
Наверное, не бывает.
singalen: (hope_never)
Наши начинают разрабатывать проект, какой-то scripting tool.
Буду сваливать сюда линки, которые найду.

Из прошлогодней Silicon Valley Patterns:
Scripting Languages, presented by Bob Evans.
Обсуждение того же.

Оттуда же: разработчики на Java очень любят BeanShell.

Что нашлось для .NET.
Статья на MSDN: "Visual Studio for Applications Provides Customized Scripting Facilities for Your .NET Project", о JScript.
http://msdn.microsoft.com/msdnmag/issues/02/08/VisualStudioforApplications/
Топик по .NET scripting на MSCE.MS.
.NET Scripting Hosts в журнале Dr Dobb's.
Топик .NET scripting на codecomments.com. Не впечатляет. Ещё посмотреть, о каких языках там речь.
Какая-то дубаень на codeproject: http://www.codeproject.com/csharp/scripting.asp.

Похоже, на .NET кругом JScript и VBScript.

Мимоходом нашлось: Hibernate prototyping in BeanShell

upd: это совсем не тот scripting.
singalen: (elvish_piper)
Вы знали? Я не знал.
В C# 2.0 есть closures (у Джо Уолнса). Прочитано у классика. У него достаточно немного коротких статей и их все стоит прочесть.

Обратите внимание на область видимости переменных:
public List<Employee> HighPaid(List<Employee> emps) {
  int threshold = 150;
  return emps.FindAll(delegate(Employee e) { 
    return e.Salary > threshold; 
  });
}
Ушёл выпить й учить матчасть.
upd: интересная цитата об аргументах против closures в Java - о выделении памяти. По ссылке от Фаулера же, в архиве Guy Steele:
One of the early design principles of Java was that heap allocation occurrs if and only if a construct involving the "new" keyword is executed. Adding full-blown closures violated this design principle. (Dynamic class loading also violated the principle, but users seemed to be comfortable with that, perhaps because they believed that "once the computation got going" no more heap allocation would occur.)
Other features for Java release 1.5 will perform certain kinds of autoboxing, which also violates the design principle. This fact will make it easier to argue for restoring full-blown support for closures in the future.


upd2: Зато в .NET нет unordered container (set-а), и такие клёвые Find()/FindAll() не существуют в IList. Отстой!

April 2017

S M T W T F S
      1
2345 678
9101112131415
16171819202122
23242526272829
30      

Syndicate

RSS Atom
Page generated 23/7/17 22:36

Expand Cut Tags

No cut tags