WRT Settings 1.20

Since I created WRT settings there weren’t too many versions. It is as simple as it gets - you have list of name value pairs, formats are well defined and that’s it.

However, Iv7777 found an issue in way how encryption works for AsusWRT v2 configuration format. He has a bit longer explanation in addition to his fix. Short version is that some random values are not working properly with Asus’ configuration file encryption. Leaving aside discussion on how useful this encryption is in the first place, I give you new version with this correction.

In addition to this major issue, there is a bugfix for handling empty DD-WRT files and program has been upgraded to use .NET Framework 4.

As always, new version is available either from application itself or from project’s page.

Weirdest Feature in C# 7

I love the new C# 7 candy. Some of them I use, some of them I will use rarely. However, there is one I don’t get at all.

Let’s imagine having a login class and a single method with kinda unusual out parameters:

public class Login {
    public string UserName { get; set; }
    public string Password { get; set; }

    public void Deconstruct(out string userName, out string password) {
        userName = UserName;
        password = Password;
    }
}

Normally you would expect to call this method as:

var login = new Login(...);

var userName, var password;
login.Deconstruct(out userName, out password);

With new out variables, this can be written a bit shorter and, in my opinion, more readable:

var login = new Login(...);
login.Deconstruct(out var userName, out var password);

What I wouldn’t expect for the life of me, would be a Tuple-like syntax:

(var userName, var password) = login;

Why?

Because it doesn’t use keyword, it doesn’t use interface, it doesn’t use attribute. Nope, it uses the magic method name. Yep method must be named Deconstruct and have two or more output parameters and the new syntax is yours to abuse.

And this is not me not liking tuples. I would be more than happy if this worked as a normal tuple returned from a more standard method call , e.g.:

(var userName, var password) = login.Deconstruct();
    public (string userName, string password) Deconstruct() {
        return (UserName, Password);
    }

I believe this magic name method is just simply a wrong way to introduce the new features. It is not discoverable, it doesn’t really read well, and it paves path for introduction of other magical method names. Didn’t IDispose and its Dispose() vs Dispose(bool) teach us anything?

I can just hope this single deviant feature among other sensible C# 7 features is just a price we pay for the night Hejlsberg got drunk. And I surely hope he will stay clean for C# 8. :)

FRS Channel Expansion

If you are in USA and fan of walkie-talkie (aka FRS) radios, you can look forward to the additional 8 channels and higher allowed output power.

It used to be that FRS (Family Radio Service) had 14 channels shared with GMRS (General Mobile Radio Service) and GMRS had additional 8 to boost. With the new rules FRS and GMRS share all the 22 channels and their only difference remains allowed output power and bandwidth (25 vs 12.5 kHz). You can check RadioReference’s handy chart.

Additional notable change is how licencing is handled - gone are double purpose FRS/GMRS radios where the only difference was honesty of user. With the new rules FRS cannot be combined with GPRS in the same radio. Thus you won’t be able to boost power in FRS radios by just a change in settings. That will also make enforcing 12.5 kHz bandwidth more easier and it will make interfacing between FRS and GPRS much more annoying for inexperienced user.

While I am really pleased by expansion of FRS channels to what every radio on market already supported, I am sad that 12.5 kHz restriction remained when equivalent GMRS channels are 25 kHz. Why the hell not allow the same bandwidth?

In any case, these changes are mostly good and improvements are just codifying what people have been doing anyhow. Only if they could drop GMRS licence altogether… :)

Shimming Lumix Battery

Illustration

Due to various first-world problems, my wife and I ended up with two different Panasonic cameras. I use quite interesting LX100 while she strongly prefers FZ300 and zoom it brings.

FZ300 uses lithium-ion DMW-BLC12 battery (7.2 V, 1200 mAh, 36.0 x 48.0 x 16.8 mm) and comes with DE-A79 battery charger. My LX100 is a bit smaller and uses DMW-BLG10 battery (7.2 V, 1025 mAh, 37.0 x 42.0 x 14.1 mm) coming with a smaller DE-A99 charger. As you can see from measurement, it is not the same battery. And no, neither charger is designed to be universal.

However, pinout and voltage is the same on both and you can sort of get smaller LX100 battery into FZ300 charger. Unfortunately, as battery is shorter, it doesn’t stay in nor it charges. Only if I could find common house-hold item that could bridge that 6 millimeter gap in length…

Well, it ends up that 4.5 mm of USB connector is just enough for flexible pins on charger to make contact with battery. And my old SanDisk USB drive fits just right.

Lazy<T>

Quite often in singleton classes you might find yourself doing the standard plumbing code like this:

private static MyClass _current = new MyClass();

public static MyClass Current {
    get { return _current; }
}

or a bit simpler with C# 7:

public static MyClass Current = new MyClass();

If class is a bit heavier (e.g. using lots of memory) you might do it lazily with a lock:

private static MyClass _current;

public static MyClass Current {
    get {
        lock(SyncRoot) {
            if (_current == null) { _current = new MyClass(); }
            return _current;
        }
    }
}

What almost never gets any love is Lazy construct known from .NET Framework 4:

private static Lazy<MyClass> _current = new Lazy<MyClass>();

public static MyClass Current {
    get { return _current.Value; }
}

This will initialize class on the first access, it is tread safe by default, and you can even use custom initializer if needed, e.g.:

private static Lazy<MyClass> _current = new Lazy<MyClass>(() =&gt; new MyClass(42));

public static MyClass Current {
    get { return _current.Value; }
}

Exactly what doctor prescribed. :)

PS: And stop using double-check locking.