20190327のKotlinに関する記事は5件です。

「一般」を「1般」に置き換えて二度見させるためだけのコードを書いた

ずいぶん前に Twitter で見かけたツイートが元ネタ.

こんな感じに文字列を変換するコードを 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
}

おわりに

「恒河沙」とかは日常会話で使おうと思っても使える気がしない.

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Corda関連のおすすめ記事一覧

Cordaに関するおすすめ記事を掲載していきます!
これからどんどん増やしていくのでお楽しみに!!

↓↓↓↓↓↓↓

Cordaで信用状取引のアプリケーションを動かしてみた1

https://qiita.com/tomoyosi/items/33d23d8037a7c1e11efe

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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 --help

helpが表示されたところで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: 19

lizardのAvgCCNは上記のmccをfunctionsで割った値になりそう

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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" />足し忘れてまたはまってました。

みんな上記のオプションを仕込むのが当たり前だから、話題になってないんだろうなと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

技術選定まとめ

技術選定まとめ

おはこんにちばんわ
マンハッタンコードエンジニアのがーたろーです。

今回プロジェクトで技術選定を行いました。
どのような観点、要素で技術を選定するべきなのかを学んだのでまとめたいと思います。

技術選定に必要なもの

観点:エンジニア、開発チームが作業するのに最適だと思えるものを選定すること

上記の最適だと思えるものには

  1. 目的
  2. メリット
  3. できることの比較

これらを満たしていることが前提になります。

今回選定の候補に選ばれた言語は
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に載っけてもいいぜって人いたらどうぞよろしくお願いします!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む