I am in the process of rewriting the libraries & parts chapter of Dart for Hipsters and it occurs to me that I do not fully understand the scoping rules for parts. Although I likely will not touch on the specific subject in the chapter, I would, for my own edification, like to know if a part can access the main library and another part.
My conceptual understanding of parts says that yes, parts should be able to access other parts as if they were all defined directly in the same file. This is, in fact, the very purpose (I think) of parts in Dart. Unfortunately, I almost have myself convinced that it will not work—mostly because I have been replacing discussions of the now defunct
#source()
directive and have myself confused. Let's see what the code says.I create
sum_of_parts.dart
with a single function that doubles a number:library sum_of_parts; part 'triple_double.dart'; part 'quadruple_triple_double.dart'; double(x) => 2 * x;This
double()
function is defined directly in the main library. I have also included two other parts for my "sum_of_parts
" library. The first is triple_double.dart
, which triples the result of the double()
function defined in the main library:part of sum_of_parts; triple_double(x) => 3 * double(x);Using the
part of
syntax to reciprocate the library's part
directive ensures that Dart will consider this to effectively be part of the main sum_of_parts
library. Thus, the triple_double()
function ought to work. Since they are both parts of the same library, I ought to be able to call one function from the other.Similarly, if the second part of my simple library,
quadruple_triple_double.dart
calls the triple_double()
function, then it ought to work:part of sum_of_parts; quadruple_triple_double(x) => 4 * triple_double(x);This will work because these "part of" the main library are another way of writing everything in a single file as:
library sum_of_parts; double(x) => 2 * x; triple_double(x) => 3 * double(x); quadruple_triple_double(x) => 4 * triple_double(x);And this does, in fact work. I write three tests to set my expectation that the three functions will return the expected quadrupling, tripling or doubling:
import 'sum_of_parts.dart' as Parts; run() { group("[main]", (){ test('can call functions defined directly in library', (){ expect(Parts.double(3), equals(6)); }); test('functions in parts can call functions defined in main library', (){ expect(Parts.triple_double(3), equals(18)); }); test('functions in parts can call functions in other parts', (){ expect(Parts.quadruple_triple_double(3), equals(72)); }); }); }And this passes:
➜ tests git:(master) ✗ dart test.dart unittest-suite-wait-for-done PASS: [main] can call functions defined directly in library PASS: [main] functions in parts can call functions defined in main library PASS: [main] functions in parts can call functions in other parts All 3 tests passed.And, just as importantly, this passes
dart_analyzer
's scrutiny:➜ tests git:(master) ✗ dart_analyzer test.dart ➜ tests git:(master) ✗Before calling it a night, I try variables as well. I define
var one = 1;
in the main library. I define var two = 2;
in triple_double.dart
and var three = 3;
in quadruple_triple_double.dart
. And in triple_double.dart
, I define a function that can use these hard coded integers to answer the eternal question of what is 1 + 2 + 3 + another number?part of sum_of_parts; triple_double(x) => 3 * double(x); var two = 2; one_plus_two_plus_three_plus(x) => one + two + three + x;Again,
one
and three
are defined in the main library and another part respectively. I write a test to verify this function as well:import 'package:unittest/unittest.dart'; import 'sum_of_parts.dart' as Parts; run() { group("[main]", (){ // ... test('parts have access to variables', (){ expect(Parts.one_plus_two_plus_three_plus(4), equals(10)); }); }); }This too passes:
➜ tests git:(master) ✗ dart_analyzer test.dart ➜ tests git:(master) ✗ dart test.dart unittest-suite-wait-for-done PASS: [main] can call functions defined directly in library PASS: [main] functions in parts can call functions defined in main library PASS: [main] functions in parts can call functions in other parts PASS: [main] parts have access to variables All 4 tests passed.Cool beans! It seems that I really do have a good conceptual model of parts. Now I just need to forget I ever knew about
#source
.Day #625
No comments:
Post a Comment