Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Samples for super-initializer and named arguments anywhere #137

Merged
merged 6 commits into from
Apr 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions parameters/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Files and directories created by pub.
.dart_tool/
.packages

# Conventional directory for build output.
build/

pubspec.lock
15 changes: 15 additions & 0 deletions parameters/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Function parameters and super-initializer samples

This sample demonstrates Dart's function parameters capabilities,
including named parameters, optional parameters, and the ability to have named
arguments anywhere in the argument list.

As well, the sample demonstrates super-initializer parameters.

These features are part of Dart 2.17. The programs in this folder won't
compile in earlier versions.

## Instructions

Read the source code in the `lib/` directory. The code is split into
separate files according to topics or use cases.
1 change: 1 addition & 0 deletions parameters/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include: package:lints/recommended.yaml
22 changes: 22 additions & 0 deletions parameters/lib/named_parameters.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// This example shows the use of named arguments and parameters.
///
/// See the test under `../test/named_parameters_test.dart` for its use.

/// Function that counts the amount of [items] that match a given [predicate],
/// with the option to skip the first [skip] elements.
///
/// This function has three parameters:
/// - Required positional parameter [predicate]
/// - Required named parameter [items]
/// - Optional named parameter [skip]
int countWhere<T>(
bool Function(T) predicate, {
required Iterable<T> items,
int skip = 0,
}) {
return items.skip(skip).where(predicate).length;
}
97 changes: 97 additions & 0 deletions parameters/lib/super_initalizer.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// This example shows the use of super-initializer parameters.
///
/// Super-initializer parameters allow to forward constructor parameters
/// to the superclass, avoiding having to write the parameter multiple times
/// in the superclass constructor invocation.

/// This example contains multiple classes representing different types of
/// synthesizers, a musical instrument similar to a piano
/// which can be used to create new sounds.
///
/// All subclasses inherit from the [Synth] class and take advantage of the
/// different super-initializer capabilities.
class Synth {
/// Model name
final String model;

/// Amount of notes that can be played at the same time
final int polyphony;

/// Amount of sound generators, default to 1
final int oscillators;

/// In the class constructor [model] is a positional parameter,
/// while [polyphony] and [oscillators] are named parameters.
Synth(
this.model, {
required this.polyphony,
this.oscillators = 1,
});

@override
String toString() {
return 'Synth $model. Polyphony: $polyphony, oscillators: $oscillators';
}
}

/// This class represents an old vintage synthesizer.
///
/// [VintageSynth] can only have 1 oscillator.
/// [polyphony] is optional and is 1 by default.
class VintageSynth extends Synth {
/// [model] is forwarded to the super constructor.
/// Named parameter [polyphony] is forwarded, with the default value of 1.
VintageSynth(super.model, {super.polyphony = 1});
}

/// This class represents a modern digital synthesizer.
///
/// [DigitalSynth] can only have 1 oscillator.
/// Named parameter [polyphony] is required.
class DigitalSynth extends Synth {
/// [model] is forwarded to the super constructor.
/// Named parameter [polyphony] is forwarded and it is required.
DigitalSynth(super.model, {required super.polyphony});

/// The following constructor declaration would not be possible
/// because [polyphony] is not a positional argument.
///
/// DigitalSynth(super.model, super.polyphony);
}

/// This class represents a complex multi-oscillator synthesizer.
///
/// [MultiOscillator] requires all three parameters.
class MultiOscillatorSynth extends Synth {
/// This constructor has three positional parameters instead of one.
///
/// [model] is forwarded to the super constructor.
/// [polyphony] and [oscillators] positional parameters are then passed to the
/// named parameters in the super constructor.
MultiOscillatorSynth(
super.model,
int polyphony,
int oscillators,
) : super(
polyphony: polyphony,
oscillators: oscillators,
);
}

/// This class represents a synth with a fixed amount
/// of polyphony and oscillators.
///
/// [FixedOscillatorSynth] only requires the positional parameter [model].
class FixedOscillatorSynth extends Synth {
/// [model] is forwarded to the super constructor.
/// [polyphony] and [oscillators] are hardcoded.
FixedOscillatorSynth(super.model)
: super(
polyphony: 1,
oscillators: 3,
);
}
12 changes: 12 additions & 0 deletions parameters/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: parameters
description: Function parameters and super initalizers examples
version: 1.0.0

publish_to: none

environment:
sdk: '>=2.17.0-182.1.beta <3.0.0'

dev_dependencies:
lints: ^1.0.0
test: ^1.16.0
55 changes: 55 additions & 0 deletions parameters/test/named_parameters_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:parameters/named_parameters.dart';
import 'package:test/test.dart';

/// This example shows the use of named arguments.
///
/// Starting in Dart 2.17, named arguments can be used at any position in the
/// arguments list, instead of only after the positional arguments.
///
/// In the following tests, the method [countWhere] is called
/// with a different argument list order to show this.
void main() {
test('named argument after positional argument', () {
final list = [0, 2, 42, 91];

// `items` named argument appears after the positional argument `predicate`
// Default argument `skip` is not provided
final total = countWhere<int>((item) {
return item % 2 == 0;
}, items: list);

expect(total, 3);
});

test('named argument before positional argument', () {
final list = [0, 2, 42, 91];

// `items` named argument appears before the positional argument `predicate`
// Default argument `skip` is not provided
final total = countWhere<int>(items: list, (item) {
return item % 2 == 0;
});

expect(total, 3);
});

test('positional argument between named arguments', () {
final list = [0, 2, 42, 91];

// positional argument `predicate` appears between
// named arguments `items` and `skip`
final total = countWhere<int>(
items: list,
(item) {
return item % 2 == 0;
},
skip: 1,
);

expect(total, 2);
});
}
30 changes: 30 additions & 0 deletions parameters/test/super_initializer_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:parameters/super_initalizer.dart';
import 'package:test/test.dart';

void main() {
test('Create multiple instances of class Synth', () {
// Constructor with optional argument, provided
final juno = VintageSynth("Juno", polyphony: 6);
expect(juno.toString(), "Synth Juno. Polyphony: 6, oscilators: 1");

// Constructor with optional argument, not provided
final tb303 = VintageSynth("TB-303");
expect(tb303.toString(), "Synth TB-303. Polyphony: 1, oscilators: 1");

// Constructor with required argument
final dx7 = DigitalSynth("DX7", polyphony: 6);
expect(dx7.toString(), "Synth DX7. Polyphony: 6, oscilators: 1");

// Constructor with required positional arguments
final ob6 = MultiOscillatorSynth("OB6", 5, 3);
expect(ob6.toString(), "Synth OB6. Polyphony: 5, oscilators: 3");

// Constructor with a single required positional arguments
final minimoog = FixedOscillatorSynth("MiniMoog");
expect(minimoog.toString(), "Synth MiniMoog. Polyphony: 1, oscilators: 3");
});
}