Override of private methods

1,169 views
Skip to first unread message

Lukas Renggli

unread,
Aug 20, 2013, 6:00:06 PM8/20/13
to General Dart Discussion
Consider the following example:

  == a.dart =============================

  library a;

  class A {
    String toString() => _p();
    String _p() => 'A';
  }

  == b.dart =============================

  library b;

  import 'a.dart';

  class B extends A {
    String _p() => 'B';
  }

  void main() {
    print(new A());
    print(new B());
  }

When running b.dart it prints "A" and "A". 

This is probably what one would expect from Java, where private methods are called based on the static type. I was surprised to find the same behaviour in Dart. Maybe the editor should show a warning in this case?

When moving the class A to the package b the output suddenly becomes "A" and "B". Again, this is probably expected, but I was surprised that a simple move of a class from a to b can subtly change its behaviour.

Long story short, this particular behaviour prevents me from subclassing SimpleConfiguration from the official unittest package. I want to redirect all output, but cannot replace the method _postMessage. Also I cannot just copy the class SimpleConfiguration, because it needs access to private fields in TestCase. Obviously I could ask the authors to make _postMessage public, but I am wondering if I am overseeing something obvious?

Lukas

Gilad Bracha

unread,
Aug 20, 2013, 6:49:36 PM8/20/13
to General Dart Discussion
Hi Lukas,

The private _p method is private to library a. So it won't be overridden by a definition in library b.  Nothing to do with types. 


--
For other discussions, see https://groups.google.com/a/dartlang.org/
 
For HOWTO questions, visit http://stackoverflow.com/tags/dart
 
To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.



--
Cheers, Gilad

Siggi Cherem

unread,
Aug 20, 2013, 7:30:29 PM8/20/13
to General Dart Discussion
Hey Lukas,

Specifically about unittest. In a way, that private method was made private on purpose to make it harder to break tests in our bots. If that method is overriden incorrectly, then some tests in dart2js appear to be "passing" while in reality they are failing silently, something which is hard to detect when it happens. For a long time I've been wanting to change how we prevent this, but we have yet to come up with a good design that we are all happy with.

Today it is possible to remove those extra print messages if you create your own configuration, it's slightly more work, but totally possible. You can extend SimpleConfiguration and not override or call super on methods that don't use _postMessage. For example, take a look in vm_config.dart and compact_vm_config.dart.

Hope this helps!
Cheers,
Siggi


jim.trainor.kanata

unread,
Aug 21, 2013, 5:29:55 AM8/21/13
to mi...@dartlang.org
Maybe file a bug report requesting a warning or hint from the analyzer
that covers the issue.

It does look like a source of surprise and confusion if one stumbles
over it. You must look at the code you are importing to know whether you
are, or are not, inadvertently overriding a private method - which isn't
the best situation. One could be bitten, also, upon updating, if an
imported class adds a private method with a name that matches a
pre-existing private method in the extending class.

Florian Loitsch

unread,
Aug 21, 2013, 5:30:31 AM8/21/13
to General Dart Discussion
An easy (simplified!) way to look at privacy in Dart: every variable that starts with "_" gets its leading "_" replaced by "library_X_" (where each library has it's own X).
In your example this becomes:

class A {
  ...
  String library_a_p() => 'A';
}
...
class B extends A {
  ...
  String library_b_p() => 'B';
}

Users can't generate these prefixes, but it makes thinking about Dart privacy easier.

--
For other discussions, see https://groups.google.com/a/dartlang.org/
 
For HOWTO questions, visit http://stackoverflow.com/tags/dart
 
To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.



--
Give a man a fire and he's warm for the whole day,
but set fire to him and he's warm for the rest of his life. - Terry Pratchett

Gilad Bracha

unread,
Aug 21, 2013, 12:05:01 PM8/21/13
to General Dart Discussion
On Wed, Aug 21, 2013 at 2:29 AM, jim.trainor.kanata <jim.train...@gmail.com> wrote:
Maybe file a bug report requesting a warning or hint from the analyzer that covers the issue.

It does look like a source of surprise and confusion if one stumbles over it. You must look at the code you are importing to know whether you are, or are not, inadvertently overriding a private method - which isn't the best situation.  

No. You never override a private method of an imported class, inadvertently or not. The problem Lukas described is the opposite - he wants to override it but cannot.
 
One could be bitten, also,  upon updating, if an imported class adds a private method with a name that matches a pre-existing private method in the extending class.

Only if it is in the same library. The situation holds for all methods that are inherited.  


Lukas Renggli wrote:
Maybe the editor should show a warning in this case?

--
For other discussions, see https://groups.google.com/a/dartlang.org/

For HOWTO questions, visit http://stackoverflow.com/tags/dart

To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.



--
Cheers, Gilad

Lukas Renggli

unread,
Aug 21, 2013, 12:20:04 PM8/21/13
to General Dart Discussion
Thanks for all the answers.

@Siggi: Overriding the methods that don't use _postMessage is a bit fragile, but it works for now. My use-case is a configuration that produces JUnit compatible XML output that can be read by many existing CI tools (https://github.com/renggli/JUnitConfigurationDart/blob/master/lib/junitconfiguration.dart). 


Cheers,
Lukas

Lukas Renggli
www.lukas-renggli.ch

Siggi Cherem

unread,
Aug 21, 2013, 1:04:11 PM8/21/13
to General Dart Discussion
On Wed, Aug 21, 2013 at 9:20 AM, Lukas Renggli <ren...@gmail.com> wrote:
Thanks for all the answers.

@Siggi: Overriding the methods that don't use _postMessage is a bit fragile, but it works for now. My use-case is a configuration that produces JUnit compatible XML output that can be read by many existing CI tools (https://github.com/renggli/JUnitConfigurationDart/blob/master/lib/junitconfiguration.dart). 

Oh cool, funny I have written very similar code but had no idea this would be useful to others too. I'll see if we can add some of this to the standard unittest package. 
Reply all
Reply to author
Forward
0 new messages