Protected members in Dart classes

February 18, 2015

In general, Dart is a well designed language, but there are some rough edges. Take for example the limited privacy options for class members: Dart only provides for private members where the boundary of privacy is the library.

While private members can get you a long way, often, what you are really looking for is a protected member, i.e. a private member that is still visible to sub-classes even if they are defined in different libraries.

I guess, the canonical example is a UI framework offering e.g. a Button class. When extending the base class to create your own FancyButton, access to 'private' implementation details is often required. Lack of protected access forces you to expose the implementation through public members.

Thankfully, there is a simple workaround. I will demonstrate with an example, leveraging the above-mentioned UI framework scenario. Let's start by defining a base Button class:

library ui.button;

// 'Public' API
abstract class Button {
  factory Button({HtmlElement host}) = ButtonImpl; // Redirecting constructor
  void click();
}

// 'Protected' implementation
abstract class ButtonImpl implements Button {
  ButtonImpl({this.host});

  int state = 0; // 'protected' implementation detail.
  
  @override
  void click() {
    this.state = 1;
    host.classes.add('selected');
  }
}

In your application, namespaced in another library, you define a custom button:

library my.app.fancy_button; // notice, this is another library

abstract class FancyButton extends Button {
  factory FancyButton({String title, HtmlElement host}) = FancyButtonImpl;
}

class FancyButtonImpl extends ButtonImpl implements FancyButton {
  String title; // voila, a protected property

  ButtonImpl({this.title, HtmlElement host}) : super(host: host);
}

You can use it like this:

final button = new FancyButton(title: "Cancel", host: element);

button.title // => cannot access!
button.state // => cannot access!

You cannot access the 'protected' members of FancyButton (or even Button's protected members, for that matter). As an added bonus, if you would like to side-step the protection (e.g. you are writing a unit-test and you would like to assert some implementation details) you can just instantiate the implementation class:

final button = new FancyButtonImpl(title: "Cancel", host: element);

expect(button.title, equals("Cancel")); // => true

While this workaround is relatively straightforward, I really hope Dart's designers will introduce a @protected annotation in the future. An annotation that is statically asserted (e.g. by the IDE or dart-analyzer) would be an elegant and practical solution.


Cool retro terminal

October 3, 2014

I dig command line terminals, I dig retro computing, I dig cool stuff. And I absolutely love this mind-blowing combination: cool-retro-term.

Amber flavor

Green flavor

Scanlines


Input font system

August 21, 2014

Apart from writing code for fun and profit, I have a thing about fonts. It's only natural then that programming fonts have a special place in my heart. Monospaced fonts are the defacto standard, but lately a radical idea came to my attention: using proportionally spaced fonts for code and leaving the actual typesetting to the editor.

While I am still not convinced, I have to admit that the proponents of the idea, came up with a beautiful family of programming fonts called 'Input'.

Input font gallery

What can I say, it's my new favorite :)


Luma

August 7, 2014

So old-school, yet so modern. I especially like the music!


Were are we today?

August 5, 2014

Is it 1880 or 1914?

A lot about where we are today has similar characteristics. We have all of the ingredients for an information society in place: a global network that connects everyone, rapidly improving machine learning and automation, additive manufacturing and robotics (to name just a few key ingredients). We also have globalized many aspects of the economy with global corporations and supply chains.

Yet again the political leadership throughout the world is still largely thinking in industrial terms, including emphasizing the nation state as the geographic organizing principle (and playing up ethnic and religious differences). Once again we also have large groups of people who feel pushed around or left behind by the emerging information economy.

I am consistently surprised that people around me don't realize what is really happening in the world today. We live in dangerous times. You better expect (and prepare for) some disruptive changes within this decade. And I am not talking about Valey-style, hipster disruption here...


Right-size precision

August 4, 2014

The need to right-size precision to save energy, bandwidth, storage, and electrical power

The representation of real numbers within computers leaves a lot to be desired. Every programmer is bitten at some point by floating point precision issues. Open a JavaScript console and type 0.1 + 0.2 for the canonical example. This fascinating paper frames the problem in whole new perspective and proposes a couple of innovative solutions. As the author says...

Let’s make computer math much smarter than what it was in 1914!


No Juju for you!

August 3, 2014

Ubuntu's Not Invented Here syndrome

A well-articulated analysis, the following quote particularly resonated with me:

I don't think that Canonical is bad at what it does. It's just that they're rarely the best and being mediocre (or even second best) isn't good enough when the tournament effect is at work. The winner takes home the pot (e.g., becomes the new standard) and Canonical isn't winning.

Switching to Unity and competing on so many fronts was a mistake, Canonical is spread too thin. Still, the latest LTS release is pretty solid and pleasingly refined. I plan to stick with Ubuntu some more, these days my mantra is to be conservative with platform changes. If things don't work-out, there is always a safe fallback.


The evolution of browsers

September 18, 2011

A new month, a new version of Chrome is released. Don't get me wrong, Web Audio is interesting (one more nail in the coffin for Flash) and Native Client may be a solution to the primary roadblock in the evolution of the Web towards an application platform (namely JavaScript).

Still, I would prefer browser vendors to go after some low-hanging fruit first. I mean, emerging HTML5 technologies are cool and all, but how about concentrating on the actual HTML part first? How about implementing common forms controls (date/time pickers, rich text editors, improved validation and more)? How about fully implementing CSS Paged Media? How about implementing MathML? How about replacing .pdf with .html first and then focus on killing Flash?

And while we are at it, how about improving bookmark management in Chrome? The current interface leaves a lot to be desired (i.g. multiple categorization of bookmarks using tags and/or hierarchical folders, similar to the categorization available in Google Docs).

In short, I would like to see more pragmatic features sooner rather than later.


Nasty Java catch

March 17, 2011

Some time ago, I wrote about a nasty JavaScript catch. Well, it seems that no language is immune from nasty surprises, so here comes one for Java:

BigDecimal value = new BigDecimal("0.31");
BigDecimal oldValue = new BigDecimal("0.34");
BigDecimal ratio = value.divide(oldValue);

throws:

java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

Funky, huh? Let me offer a quick fix:

BigDecimal ratio = value.divide(oldValue, BigDecimal.ROUND_HALF_EVEN);

For some intuition (in Khan's parlance), have a look here.


Ultra geeky holiday e-Card

February 4, 2011

This came to my attention and I had to share it:


Read older posts in the archive, or subscribe to the feed.