昨日の続きを調べて、一応やりたかったことは実現できたのでブログにも書いておく。
サンプルコード
gist のコードの通りだけど、 Generics を使ってクラスの初期化時に Comparable に使う struct を渡せるようにしている。
こうやっておけば let array = [A<Q>()]
みたいに同じ Comparable の型に限定した Array が作れて型安全。
昨日の続きを調べて、一応やりたかったことは実現できたのでブログにも書いておく。
gist のコードの通りだけど、 Generics を使ってクラスの初期化時に Comparable に使う struct を渡せるようにしている。
こうやっておけば let array = [A<Q>()]
みたいに同じ Comparable の型に限定した Array が作れて型安全。
Generics 周りの挙動の備忘録。 適当な空のクラスをマーカーとして、メソッドの振る舞いを変えられた。
WIP Pull Request Unhighlignter for GitHub が便利で今まで使っていたけど、昨日突然使えなくなった。
※ 原因はGitHubのCSSセレクタが変わったため。現在は kyanny/chrome-ext-wip-pull-request-unhighlighter-for-github#6 がマージされ動くようになってる。
待っていれば直ると思ったけど、予想以上に無いと困ったので最低限の機能を Tampermonkey の UserScript として再実装した。 ついでに、 pjax で画面遷移した時も動くようにした。
本当はプルリク投げた方が良いかなーと思いつつ、CSSセレクタの指定は好みある*1だろうし、テストコードも無かったので面倒で止めた。
*1:個人的にはclass指定よりidの方が壊れにくいと思うけど、本家はclass使っている
今日やってた勉強内容。
$ git clone https://github.com/sinsoku/study.git $ cd study/swift $ bin/run swift build -C PlayGround $ bin/run swift test -C PlayGround
// PlayGround/Sources/PlayGround/SimpleClass.swift class BaseClass { let number: Int = 0 let string: String? = nil } class SimpleClass: BaseClass { }
// PlayGround/Tests/PlayGround/SimpleClassTests.swift import XCTest @testable import PlayGround class SimpleClassTests: XCTestCase { func testSimpleClassBehavior() { let obj = SimpleClass() // refs: https://stackoverflow.com/questions/25725033/swift-too-smart-checking-an-objects-type-when-testing-with-xctest XCTAssertTrue((obj as Any) is SimpleClass) XCTAssertTrue((obj as Any) is BaseClass) } // refs: https://github.com/apple/swift/blob/swift-DEVELOPMENT-SNAPSHOT-2016-06-06-a/stdlib/public/core/Mirror.swift#L137 func testReflectionBehavior() { let playGround = Mirror(reflecting: PlayGround()) XCTAssertEqual(playGround.description, "Mirror for PlayGround") XCTAssertEqual(playGround.displayStyle, Mirror.DisplayStyle.struct) XCTAssertTrue(playGround.subjectType == PlayGround.self) let base = Mirror(reflecting: BaseClass()) XCTAssertEqual(base.description, "Mirror for BaseClass") XCTAssertEqual(base.displayStyle, Mirror.DisplayStyle.class) XCTAssertTrue(base.subjectType == BaseClass.self) let simple = Mirror(reflecting: SimpleClass()) XCTAssertEqual(simple.description, "Mirror for SimpleClass") XCTAssertEqual(simple.displayStyle, Mirror.DisplayStyle.class) XCTAssertTrue(simple.subjectType == SimpleClass.self) let parent = simple.superclassMirror XCTAssertEqual(parent?.description, "Mirror for BaseClass") XCTAssertEqual(parent?.displayStyle, Mirror.DisplayStyle.class) XCTAssertTrue(parent?.subjectType == BaseClass.self) let defNumber = base.children.filter { $0.label == "number" }[0] XCTAssertEqual((defNumber.value as! Int), 0) let defString = base.children.filter { $0.label == "string" }[0] // FIXME: the assertion is failed. (XCTAssertNil failed: "nil") // XCTAssertNil(defString.value) XCTAssertEqual(String(defString.value), "nil") } static var allTests : [(String, (SimpleClassTests) -> () throws -> Void)] { return [ ("testSimpleClassBehavior", testSimpleClassBehavior), ("testReflectionBehavior", testReflectionBehavior), ] } }
value の型が Optional<String>
にはなっているっぽいのに、なぜか nil
にはならずにテストが通らなかった。
結局、よく分からないまま・・・。
class Foo { let number: Int? = nil } let m = Mirror(reflecting: Foo()) let defNumber = m.children.filter { $0.label == "number" }[0] defNumber.value == nil // Playground execution failed: MyPlayground.playground:1:17: error: value of type 'Any' (aka 'protocol<>') can never be nil, comparison isn't allowed // defNumber.value == nil //~~~~~~~~~~~~~~~ ^
エラーでるけど、結局 value
の返す値が何なのかが不明・・・。
この前作った Swift の環境 で勉強として FizzBuzz を書いてみた。
$ mkdir FizzBuzz $ cd FizzBuzz $ swift package init
// Sources/app/FizzBuzz.swift class FizzBuzz { let num : Int init(num : Int) { self.num = num } func toString() -> String { switch self.num { case let n where n % 15 == 0: return "FizzBuzz" case let n where n % 3 == 0: return "Fizz" case let n where n % 5 == 0: return "Buzz" default: return String(self.num) } } }
// Tests/app/FizzBuzzTests.swift import XCTest @testable import app class FizzBuzzTests: XCTestCase { func testThree() { let fizzBuzz = FizzBuzz(num: 3) XCTAssertEqual(fizzBuzz.toString(), "Fizz") } func testFive() { let fizzBuzz = FizzBuzz(num: 5) XCTAssertEqual(fizzBuzz.toString(), "Buzz") } func testFifteen() { let fizzBuzz = FizzBuzz(num: 15) XCTAssertEqual(fizzBuzz.toString(), "FizzBuzz") } func testOther() { let fizzBuzz = FizzBuzz(num: 1) XCTAssertEqual(fizzBuzz.toString(), "1") } static var allTests : [(String, (FizzBuzzTests) -> () throws -> Void)] { return [ ("testThree", testThree), ("testFive", testFive), ("testFifteen", testFifteen), ("testOther", testOther) ] } }
$ swift build $ swift test
Travis CI で npm package を自動リリースできるっぽいので、設定してみた。
そして、失敗したので deprecate した話。
npm Releasing
https://docs.travis-ci.com/user/deployment/npm
clairvoyance の npm publish を自動化してみようと、上記のページを参考に設定してみた。
# .travis.yml deploy: provider: npm email: sinsoku.listy@gmail.com on: tags: true
npm の api token は npm login
を実行すると、 ~/.npmrc
に追記されるので、それを travis
コマンドで設定する。
$ travis encrypt YOUR_API_KEY --add deploy.api_key
あとは git tag
でタグを作成し、 git push origin v0.4.1
でプッシュすると自動的に publish された。
新しいバージョンである v0.4.1 が自動的に publish されたが、パッケージが壊れていた。
原因は gulp build
した後のファイルがパッケージに含まれていないため。
このあたり を読むと、 .npmignore
がない場合、デフォルトでは .gitignore
を参照するっぽい。というわけで、 .npmignore
を用意した。
coverage/ maps/ node_modules/ src/ test/
そして、新たに v0.4.2
のタグを作ってプッシュしたところ、動くようになった。
公開してしまった v0.4.1
は deprecate
にしておいた。
$ npm deprecate clairvoyance@0.4.1 "v0.4.1 does not work, please upgrade to v0.4.2."
ちゃんとインストールするときに WARNING が出るようになってた。
$ npm i clairvoyance@0.4.1 npm WARN deprecated clairvoyance@0.4.1: v0.4.1 does not work, please upgrade to v0.4.2.
docker で勉強する環境を作ってみた。
リポジトリと README を見てもらえば分かるけど、下記のような bin/run
のスクリプトを用意する。
#!/bin/sh if [ -n "$*" ] then docker run -v $(pwd):/app -w /app swiftdocker/swift $* else docker run --privileged -it swiftdocker/swift swift fi
REPL で試したい場合は bin/run
を実行する。
$ bin/run Welcome to Swift version 3.0-dev (LLVM 8fcf602916, Clang cf0a734990, Swift 000d413a62). Type :help for assistance. 1>
終了するときは :exit
を入力する。
*.swift
を実行したいときは bin/run swift sample/hello.swift
のように実行する。
$ bin/run swift sample/hello.swift Hello, World!