- 投稿日:2019-03-27T20:50:50+09:00
「一般」を「1般」に置き換えて二度見させるためだけのコードを書いた
ずいぶん前に Twitter で見かけたツイートが元ネタ.
「一般」を「1般」と書くツイートが流れてきて思わず2度見。1発では変換できないから入力が7面倒くさそう。このツイートも4苦8苦、いや1000辛10000苦の末に成っている。100000000劫な身にはつらい。ことばの世界の豊10^28さを改めて感ずるが、何故そこまで、と10^40直10^48めて10^64だ
— 西練馬@3/30ようこそ福熊商店へA02 (@nishinerima) 2019年3月9日こんな感じに文字列を変換するコードを Kotlin で書いてみる.
なぜ Kotlin なのか? それは IntelliJ を立ち上げたらたまたま Kotlin のプロジェクトが開いたからである.仕様
以下のテストコードを満たすように作る.
import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test internal class WordConverterKtTest { @Test fun `漢字を指数表記に置換できる`() { // Setup val input = "こんなコードが万に一つでも役に立つのか正直極めて不可思議だ" val expected = "こんなコードが10^4に1つでも役に立つのか10^40直10^48めて10^64だ" // Exercise val result = toExponentialNotation(input) // Verify assertEquals(expected, result) } }実装
Enum を2つと Package-level function を1つ作った.
internal enum class DecimalNumber(val jaNotation: String, val number: Int) { ICHI("一", 1), NI("二", 2), SAN("三", 3), SHI("四", 4), GO("五", 5), ROKU("六", 6), NANA("七", 7), HACHI("八", 8), KYUU("九", 9) } internal enum class UnitOfNumber(val jaNotation: String, val exponent: Int) { JUU("十", 1), HYAKU("百", 2), SEN("千", 3), MAN("万", 4), OKU("億", 8), CHOU("兆", 12), KEI("京", 16), GAI("垓", 20), JO("?", 24), JOU("穣", 28), KOU("溝", 32), KAN("澗", 36), SEI("正", 40), SAI("載", 44), GOKU("極", 48), GOUGASHA("恒河沙", 52), ASOUGI("阿僧祇", 56), NAYUTA("那由他", 60), FUKASHIGI("不可思議", 64), MURYOUTAISUU("無量大数", 68) } fun toExponentialNotation(word: String): String { var result = word DecimalNumber.values().forEach { result = result.replace(it.jaNotation, it.number.toString()) } UnitOfNumber.values().forEach { result = result.replace(it.jaNotation, "10^${it.exponent}") } return result }おわりに
「恒河沙」とかは日常会話で使おうと思っても使える気がしない.
- 投稿日:2019-03-27T19:03:44+09:00
Corda関連のおすすめ記事一覧
- 投稿日:2019-03-27T15:16:19+09:00
Kotlinでdetektを使って複雑度を測る
動機
Kotlinで雑度度(complexity)を取りたい動機がある
ただし、lizardでは未対応らしく別のものを探してみるメトリクスをそのまま図るというよりKotlin向けのツールキットを利用するのが良さそう
detekt
Code smell analysis for your Kotlin projectsらしいサイトのFetureリストにある、
Complexity report based on logical lines of code, McCabe complexity and amount of code smells
を利用して使い方
gradle経由で利用出来るみたいだが、コマンドラインでの利用用途が多いのでQuickStartの方法でjarを作成する
git clone https://github.com/arturbosch/detekt cd detekt ./gradlew build shadowJar java -jar detekt-cli/build/libs/detekt-cli-[version]-all.jar --helphelpが表示されたところでjarを実行してみる
app/src/main 以下にKotlinのファイルがあるとして-iオプションで指定してみるjava -jar detekt-cli-[version]-all.jar app/src/main .................................................................................................................................................................................................... 19 kotlin files were analyzed. Ruleset: comments Ruleset: complexity - 4h debt ComplexMethod - 12/10 - [onMeasure] at XXX.kt:32:5 NestedBlockDepth - 4/4 - [onMeasure] at XXX.kt:32:5 LongMethod - 79/60 - [showDirectionalMessage] at XXX.kt:32:5 ...LongMethodなどの解析もしてくれるが、ComplexMethodを知りたいのでgrepしたりして対応してみるのが良さそう
また統計情報も出してくれるので指標として確認してみましょう(下の数値は適当です)Complexity Report: - 1161 lines of code (loc) - 942 source lines of code (sloc) - 690 logical lines of code (lloc) - 47 comment lines of code (cloc) - 142 McCabe complexity (mcc) - 146 number of total code smells - 4 % comment source ratio - 181 mcc per 1000 lloc - 226 code smells per 1000 lloc Project Statistics: - number of properties: 113 - number of functions: 52 - number of classes: 31 - number of packages: 5 - number of kt files: 19lizardのAvgCCNは上記のmccをfunctionsで割った値になりそう
- 投稿日:2019-03-27T02:06:43+09:00
OkHttp3をAndroidで使おうとしたときにjava.lang.ClassCastException: Bootstrap methaod returned nullが発生して初期化に失敗する
TL;DR
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.myapplication, PID: 12443 java.lang.BootstrapMethodError: Exception from call site #5 bootstrap method at okhttp3.internal.Util.<clinit>(Util.java:87) at okhttp3.internal.Util.skipLeadingAsciiWhitespace(Util.java:321) at okhttp3.HttpUrl$Builder.parse(HttpUrl.java:1313) at okhttp3.HttpUrl.get(HttpUrl.java:917) at okhttp3.Request$Builder.url(Request.java:165) at com.example.myapplication.com.example.myapplication.util.HttpUtil.httpGet(HttpUtil.kt:8) at com.example.myapplication.MainActivity$onParallelGetButtonClick$1$1.invokeSuspend(MainActivity.kt:33) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32) at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:236) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594) at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:742) Caused by: java.lang.ClassCastException: Bootstrap method returned null at okhttp3.internal.Util.<clinit>(Util.java:87) at okhttp3.internal.Util.skipLeadingAsciiWhitespace(Util.java:321) at okhttp3.HttpUrl$Builder.parse(HttpUrl.java:1313) at okhttp3.HttpUrl.get(HttpUrl.java:917) at okhttp3.Request$Builder.url(Request.java:165) at com.example.myapplication.com.example.myapplication.util.HttpUtil.httpGet(HttpUtil.kt:8) at com.example.myapplication.MainActivity$onParallelGetButtonClick$1$1.invokeSuspend(MainActivity.kt:33) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32) at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:236) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594) at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:742)上記の類似のエラーが発生した場合は以下のオプションをbuild.gradleに追加しBuild -> Clean Projectをする
android { compileOptions { targetCompatibility = "8" sourceCompatibility = "8" } }https://github.com/square/okhttp/issues/4597
事の始まり
Androidは浦島太郎なので、kotlinでも触るかと思って、いろいろと試していた。
APIを叩きたいと思ったのでokhttpを導入してみた。
導入の参考に以下の記事を使わせていただいた。
https://qiita.com/jonghyo/items/bf3e4e06022eebe8e3ebところが、実行すると落ちてしまう。
ということで調査をしてみた。
ログには以下のような出力がされていた。E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.myapplication, PID: 12443 java.lang.BootstrapMethodError: Exception from call site #5 bootstrap method at okhttp3.internal.Util.<clinit>(Util.java:87) at okhttp3.internal.Util.skipLeadingAsciiWhitespace(Util.java:321) at okhttp3.HttpUrl$Builder.parse(HttpUrl.java:1313) at okhttp3.HttpUrl.get(HttpUrl.java:917) at okhttp3.Request$Builder.url(Request.java:165) at com.example.myapplication.com.example.myapplication.util.HttpUtil.httpGet(HttpUtil.kt:8) at com.example.myapplication.MainActivity$onParallelGetButtonClick$1$1.invokeSuspend(MainActivity.kt:33) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32) at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:236) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594) at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:742) Caused by: java.lang.ClassCastException: Bootstrap method returned null at okhttp3.internal.Util.<clinit>(Util.java:87)
java.lang.BootstrapMethoderrorって何だろう?と思って公式のドキュメントも見てみたが動的読み込みに失敗したときにおこるということ以上の事はよくわからない。デバッグしてもなぜか本当に落ちる。よくわからない。
仕方がないのでググる
https://github.com/square/okhttp/issues/4597
すると上記のissueが見つかった。
JakeWhartonさん曰く3.13以上のOkHttpではJava8機能をビルド時に有効にする必要があるとのこと。
OkHttp requires that you enable Java 8 in your builds to function as of 3.13 and newer.
とのことなので、JakeWhartonさんの書いているコードを仕込む。
android { compileOptions { targetCompatibility = "8" sourceCompatibility = "8" } }これで動くぞやれやれと思っていたら動かなくて焦ったのですが、ちょっと読み進めると動かないよーって言ってる人がいてそうそう動かないよ。とか思ってたのですが、
上記のissueの下の方でeddexさんが
build.gradleを変更したらBuild -> clean buildを忘れずにやってね。と書いていました。試してみたところ無事動いてめでたしめでたしという感じでした。
因みに久しぶりすぎて、マニフェストに
<uses-permission android:name="android.permission.INTERNET" />足し忘れてまたはまってました。みんな上記のオプションを仕込むのが当たり前だから、話題になってないんだろうなと思います。
- 投稿日:2019-03-27T01:16:13+09:00
技術選定まとめ
技術選定まとめ
おはこんにちばんわ
マンハッタンコードエンジニアのがーたろーです。今回プロジェクトで技術選定を行いました。
どのような観点、要素で技術を選定するべきなのかを学んだのでまとめたいと思います。技術選定に必要なもの
観点:エンジニア、開発チームが作業するのに最適だと思えるものを選定すること
上記の最適だと思えるものには
- 目的
- メリット
- できることの比較
これらを満たしていることが前提になります。
今回選定の候補に選ばれた言語は
1. Kotlin/SpringBoot
2. ruby/Ruby on Rails
3. php/Laravelの三つから選びます。
目的
API通信、管理画面、複数のサーバーとデータ通信をするためのサーバーを作る
オニオンアーキテクチャ、DDDの理解、学習
GraphQL使いたい
テスト駆動メリット&デメリット
kotlin/SpringBoot
メリット
今回のプロジェクトではアプリ側(スマートフォン)の開発も行うため、Andoroidの開発にKotlinを用いる。
そのため学習する言語がSwift+Kotlinの2言語で済む。
DDD(ドメイン駆動開発)と親和性が高いデメリット
インフラにかかる影響の判断が他の2言語と比べて手間がかかる。(tomcatの設定周り)
サーバーでKotlin(Java)を使う場合、Tomcatが必須になる。
Tomcatを利用する場合、Nginxとは異なりユーザーの最大同時接続数の管理がスレッドをいくつまで立てられるかの設定になる。
何スレッドまで利用するのかはサーバースペックを元に試算しなければ行けないためサーバーのスペック調査
設定数のMaxギリギリまで接続した場合の挙動のテストをして性能を担保しないといけない(やること増える)Ruby/Ruby on Rails
メリット
プロジェクトにRuby on Railsを触ったことのあるエンジニアが3人いる。
ディレクトリ構造など規約があるため、設計の話し合いコストが減る。
ライブラリがとにかく便利(使ったことあるやつがそのまま使えそう)デメリット
DDDとrailsの作りがおそらくケンカする。
DDDでやりたいことがrailsに合わせないと、そもそも作れなくなるためサーバー側だけ全体と作りが変わってきてしまう。PHP/Laravel
メリット
自由
DDDと親和性がある
railsを参考に作っているためライブラリの使い方が似ていそう。
ローカルでの環境作成が容易なため、開発に入るまでのスピードが早い。デメリット
規約、設計を設けないと開発現場が魔界と化す。できることの比較
候補 サーバ設定の難易度 GraphQL DDD 規約 テスト Kotlin/SpringBoot 性能試験が必要 チューニング OK ◉ ktlint Spek Mockit Ruby/Ruby on Rails nginx(むずかしくない) OK △ Rubocop Rspec PHP/Laravel nginx(むずかしくない) OK ○ PSR phpUnit phpspefc ミドルウェアはnginxを全部使う想定。
Kotlinだけ考えること増える。
規約、テストは使うものが違うだけで問題はない。ぶっちゃけどれ使いたい?
ここまで議論した結果、要件はどれでも実現可能
学習コスト的にはKotlinサーバーの書き方はAndroidとは異なる
やったことある人が多いのはメリットだが少ないのはデメリットではない(世界で使っている人が少ないのは別)
DDD・オニオンアーキテクチャに沿った開発をしたい。やらないともったいない。
↑これに力を入れたいのでデメリット=インフラ課題を増やしたくはない上記のことを考慮した結果
選ばれたのはPHP/Laravelでした
まとめ
今回私は開発チームの一員として使用する言語の技術選定を行いました。
その中で、何を観点に持たないといけないのか、懸念点、優先すべき事柄、そういった判断基準を身に着けるいい機会を頂けました。
この話をするときにもっといろんな知識があったらもっと別の視点でも話ができたんだろうなぁ、と次にする際にはいろんな知識を身につけてから挑戦したいなぁ、と思いました。インフラって全くワカンねぇなぁ。
ファンを増やしたいのでもしこの記事いいなぁ、お前やるじゃんとか思ったらファンメッセージください!
もし会社のHPに載っけてもいいぜって人いたらどうぞよろしくお願いします!