Kotlinの ?.let とか run とかをDartで使うためのパッケージを作ってみた

まえおき

always DRINKのパス表示アプリをFlutterで作ってみた - YusukeIwakiのブログ をやってたときに、

「Kotlinだったら ?.let でサクッと書けるのになー・・・」ってのを何度となく感じていた。

f:id:YusukeIwaki:20191106101230p:plain

でも言語仕様的に拡張はできないしな〜。と。そんなときにTwitterを見てたら

おおお。まじで??メソッド生やせるの???ええやん?

ということで、速攻やってみることにした。

パッケージを作るのはとても簡単

npm init てきなものはDartにはない。(参考: Dartのパッケージマネージャーのpubにはinitコマンドがない - Qiita )一応、stagehand っていうパッケージ雛形はあるんだけど、勉強がてら手で作ってみることにした。

pubspec.yamllib/ example/ test/ あたりを既存のパッケージの真似をして作ればいいだけで、かなり簡単だ。

Dart 2.6の static extension methods を使うところは

github.com

とかをかなり参考にさせてもらった。今回は ?.let を使いたいのが要望の9割だったので

extension ScopeFunctionsForObject<T extends Object> on T {
  ReturnType let<ReturnType>(ReturnType operation_for(T self)) {
    return operation_for(this);
  }
}

こんな感じで。ユニットテストtestパッケージ だけで

import 'package:test/test.dart';
import 'package:kotlin_flavor/scope_functions.dart';

void main() {
  group('.let', () {
    test('for simple integer', () {
      var result = 3.let((x) => x * 2);
      expect(result, equals(6));
    });

    test('for simple string', () {
      var result = "hoge".let((String x) => x.toUpperCase());
      expect(result, equals("HOGE"));
    });

    test('type conversion', () {
      var result = "123".let((String x) => int.parse(x));
      expect(result, equals(123));
    });

    test('with Null-Aware operators', () {
      String target;
      var result = target?.let((String s) => 'target is ${s}');
      expect(result, equals(null));

      target = "hogehoge";
      result = target?.let((String s) => 'target is ${s}');
      expect(result, equals('target is hogehoge'));
    });
  });
}

ものすごい雑に書いただけだが、動いた。

CIもメッチャ簡単に設定できる

GitHub ActionsにDart用の雛形がある。(pubspec.yaml が置いてあって、そこそこDartのコードをコミットしたらGitHubが自動判別してサジェストしてくれる!)

f:id:YusukeIwaki:20191106103142p:plain

DartのDockerも信頼と実績のGoogle製のものが提供されている。

hub.docker.com

ということで、セットアップ自体はまじで簡単だった。

github.com

個人的に、dartfmt忘れが何度もあったので、そこだけ

f:id:YusukeIwaki:20191106103351p:plain

こんな感じでチェックを追加した。

後追いでLinterを追加したりもした。

github.com

いずれにしても、全くハマるところはなく、快適に設定ができた。

pub publish するまで

これがちょっとだけ厄介だった。

LICENSEがないとpublishできない

まぁ当たり前といえば当たり前。

f:id:YusukeIwaki:20191106102119p:plain

GitHubが自動的にMITライセンスのひな形とか作ってくれるので、今回はそれに頼った。

独自ドメインを持っていないと、メールアドレス公開の刑に処される

pub publishGoogleアカウントがあれば誰でもできるんだけど、Verified Publisherではない人がアップロードしたパッケージはメールアドレスが思いっきりパッケージページに載せられてしまう。 dartxパッケージ は2019/11/05現在、まだVerified Publisherにされてないので、

f:id:YusukeIwaki:20191106102401p:plain

メールアドレスが公開されている。

Verified Publisherになるには、独自ドメインDNSレコードを管理(正確には、TXTレコードに任意の文字列を設定できる状態に)している必要があって、サブドメインでもいいから自前でドメインを取得する必要がある。

それをやるとようやく、メールアドレス公開の刑から解放される。

そんなわけで

Dart 2.6公開 の2日前くらいに、パッケージを無事に公開しましたとさ。

pub.dev