Gradleのエラー

はじめに

こんなエラーが出た。

エラー: メイン・クラスworker.org.gradle.process.internal.worker.GradleWorkerMainを検出およびロードできませんでした
原因: java.lang.ClassNotFoundException: worker.org.gradle.process.internal.worker.GradleWorkerMain
Process 'Gradle Test Executor 81' finished with non-zero exit value 1
org.gradle.process.internal.ExecException: Process 'Gradle Test Executor 81' finished with non-zero exit value 1

何をやったら出たか

以下のように、キャッシュを消した後に./gradlew buildを実行したら出ました。

$ rm -rf ~/.gradle/cashes
$ ./gradlew build

解決方法

以下のように、プロジェクトルートにある.gradleディレクトリを削除後に./gradlew buildを実行すると解消されました。

$ rm -rf $PROJECT_ROOT/.gradle

原因

わかりません。ただ、Gradleのディレクトリ構成等を学習する必要がありそうです。とりあえず以下をそのうち読む。

docs.gradle.org

セレクトボックスのスタイリング

やること

セレクトボックスをCSSでスタイリングする

初めに

すでに出来合いのセレクトボックスを利用することが多いので自分でちゃんとやったことなかったなーと思い、セレクトボックスのスタイリングをしてみました。
めちゃくちゃ基本的なHTMLとCSSしか使用していませんので、基礎の基礎って感じですね。

実践

ではやっていきましょう。

html

使用するHTMLはこんな感じになっています。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/styles.css">
    <title>My test page</title>
</head>
<body>
    <div class="container">
        <div class="select">
            <select>
                <option>未選択</option>
                <option>いちご</option>
                <option>みかん</option>
                <option>すいか</option>
            </select>
        </div>
    </div>
</body>
</html>

初期状態

初めに何もスタイリングしない状態のセレクトボックスを見てみましょう。
f:id:sho03:20220125182236p:plain

うーんダサい。今時こんなセレクトボックスを見かけることはほぼないでしょう。

矢印を消す

まずは右端にある矢印を消してしまいましょう。

appearance: none;

はい、これだけで右端の矢印は消えます。

f:id:sho03:20220125182626p:plain

セレクトボックスを大きくする

今の状態のセレクトボックスだと、余白がなさすぎて文字が非常に読みづらいものとなっています。   そこで、paddingを用いて上下左右に少し余白を持たせることにしましょう。

padding: 10px 20px;

f:id:sho03:20220125183246p:plain

枠線を調整する

セレクトボックスを囲っている枠線を少し調整します。今回は青っぽい色にしましょう。

    border: 1px solid skyblue;
    border-radius: 8px;
    outline: none;

f:id:sho03:20220125183706p:plain

徐々にいい感じになってきましたか? 続いて最初に消してしまった矢印を追加しましょう。

ここまでで、selectに対するスタイルは以下のようになっていると思います。

select {
    /* 矢印を消す */
    appearance: none;
    /* 余白を持たせる */
    padding: 10px 20px;

    /* 枠線の調整 */
    border: 1px solid skyblue;
    border-radius: 8px;
    outline: none;

    width: 100%;
}

矢印を追加する

矢印の追加は擬似要素を利用します。

.select {
    width: 100px;
    position: relative;
}

/*`after`が擬似要素。他にも色々あります*/
.select::after{
    position: absolute;
    top: 1.0em;
    right: 0.9em;
    width: 0;
    height: 0;
    padding: 0;
    content: '';
    border-left: 6px solid transparent;
    border-right: 6px solid transparent;
    border-top: 6px solid blue;
    pointer-events: none;
}

最終的には以下のようになります。

f:id:sho03:20220125185124p:plain

「多様性の科学」を読みました

年末年始、暇だったので「多様性の科学」という本を読みました。この記事はその感想をつらつら書こうというものです。

多様性

多様性という言葉が声高に叫ばれてからどのくらい経ったでしょうか。
感覚的には多様性が重要(らしい)ということは現代に生きる人間であれば重々承知していることと思いますが、果たして多様性はこの社会においてどの程度重要なのでしょうか?

例えばこの記事を読んでくださっているあなたの会社組織において、多様性に富む社員構成になるとどんないいことがあるのでしょう?  

本書では、色々な実験結果や事故・事件を取り扱いつつ、多様性の持つ力をつまびらかにしていこうとする内容になっています。

異なる視点を持つ

組織に属している以上、諸々の問題ということから逃れることはできません。そして、現代の問題は、一昔前と比べると非常に高度かつ複雑化しています。
そういった問題を一人(もしくは一様的な組織)の力で解決に導くことは かなり困難になってきていることと思います。

そこで重要になってくるのは「多様な視点・思考から物事を見つめ直すこと」です。 様々な視点から問題を探ることで、新たな解決案や打開策が生まれることは想像に難くないでしょう。

異なる意見を受け入れる

多様性溢れる組織を目指すためには、当然ながら自分と異なる考えを持つ人間を受け入れる土壌ができていなければなりません。
これは組織にいる人間たち個人個人が意識していく必要があると考えています。

自分と似た人間を採用しやすい?

本書では、採用において「自分と似た傾向にある人間を採用しやすい」ことにも触れています。白人なら白人を日本人なら日本人を、といったところでしょうか。(かなり単純化していますが。)
これは、採用に限らず、例えば同じ都道府県出身の人間に対してシンパシーを感じる、のようなことが身近な例でしょうか。
その程度ならば良いのですが、これがひどくなってしまうと人種・性別など同じ属性を持つ人物を採用してしまう傾向が出てきてしまいます。これの厄介なところは「本人にその自覚がない」ということです。
意図して別の属性を持つ人間を排除しているわけではないので本人も気付きづらい、ということは頭の片隅に覚えておいたほうが良いでしょう。

とはいえ、「だからと言って同じ属性だから」という理由で採用しないということも考えものではあるのですが・・。

平均の罠

みなさん、平均は好きですか? 平均年収より高い、平均身長より低い・・平均という指標は、属している集団の中で自分がどの程度の人間なのか?を表すとても便利な数字だとは思います。
ただその一方で、「平均」という数字の持つ危険さも理解していなければなりません。 例えば本書では、航空機の座席設計をパイロットの身体的特徴の平均から割り出していたことが、航空機事故の原因のひとつになっていたという事例が載っています。
詰まるところ、平均に合致する人間がいなかった、という想定とは真逆の結果となってしまったのです。(結果として、座席の高さやレバーの位置をパイロット自身で調整できるような座席にすることで事故は減ったそうです。)

ここで重要なことは、「平均」は多様性とは反対の結果を生み出す、ということです。
身長の例で言うならば、日本で言えば170cm前後に従って家具などの設計をすることが一見合理的ではありますが、身長200cmに届くような方にとっては全くもって使いづらいものとなってしまいます。 多少極端な例となってしまいますが、平均の数値ばかりに重きを置いてしまうと、かなり視野が狭くなってしまうと言うことは注意しましょう。

終わりに

とりあえず読んでいて印象的だったところを抜き出してみました。
他にもたくさんあるのですが、これ以上書く元気がありません・・。興味のある方はぜひ読んでみてください。

多様性の科学 画一的で凋落する組織、複数の視点で問題を解決する組織

ResponseEntityでの各HTTPステータスレスポンス作成方法

はじめに

本記事では、Springで提供されているResponseEntityを使用したレスポンス作成方法について記述します。
主にHTTPステータス200系(成功)と、400・500系(エラー)の取り扱い方法です。
(個人的によく使うものだけです。悪しからず)

ResponseEntityとは

ResponseEntityは、その名の通り、レスポンスを表現するためのクラスです。
以下、ドキュメントから抜粋です。

HttpStatus ステータスコードを追加する HttpEntity の拡張。RestTemplate および @Controller メソッドで使用されます。

それでは以下、各HTTPステータスごとの書き方を列挙していきます。

なお、コードはKotlinで書きますが、Javaとそう大きく変わりませんので、Java使いの方も理解は難しくないかと思います。

共通の例

はじめに、ResponseEntityにHTTPステータスを設定する方法を書いてしまいます。

ResponseEntity.status(200).build

はい、上記のように、status(XXX)の部分を変えてしまえば、期待するHTTPステータスを持ったResponseEntityを作成することができます。
以降で紹介するのは上記コードを実現するためにあらかじめ用意されているメソッド群の紹介となります。

200系(成功)

200 OK

    // 200 no body
    fun sample200(): ResponseEntity<Void> {
        return ResponseEntity.ok().build()
    }

    // 200 contains response body
    fun sample200Body(): ResponseEntity<String> {
        return ResponseEntity.ok("Hello, World!")
        // ResponseEntity.ok().body("Hello, World!")と等価
    }

201 Created

    // 201
    fun sample201(): ResponseEntity<Void> {
        val uri = URI.create("created/uri")
        return ResponseEntity.created(uri).build()
    }

202 Accepted

    // 202
    fun sample202(): ResponseEntity<Void> {
        return ResponseEntity.accepted().build()
    }

204 No Content

    // 204
    fun sample204(): ResponseEntity<Void> {
        return ResponseEntity.noContent().build()
    }

400・500系(失敗)

400 Bad Request

    // 400
    fun sample400(): ResponseEntity<Void> {
        return ResponseEntity.badRequest().build()
    }

401 Unauthorized

    // 401
    fun sample401(): ResponseEntity<Void> {
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build()
    }

403 Forbidden

    // 403
    fun sample403(): ResponseEntity<Void> {
        return ResponseEntity.status(HttpStatus.FORBIDDEN).build()
    }

404 Not Found

    // 404
    fun sample404(): ResponseEntity<Void> {
        return ResponseEntity.notFound().build()
    }

500 Internal Server Error

    // 500
    fun sample500(): ResponseEntity<Void> {
        return ResponseEntity.internalServerError().build()
    }

終わりに

以上、よく使うであろうHTTPステータスごとのResponseEntityオブジェクトの生成方法でした。
ResponseEntityは内部的にBuilderパターンによるオブジェクト生成を行っているため、HTTPステータス以外にもヘッダーなどを設定するに便利なメソッドが多数用意されています。
それらもいずれ紹介できればと思います。

CRUDとHTTPメソッドの対応

はじめに

データベースに対する操作であるCRUDと、それらを実現するためのHTTPメソッドについての対応表です。

対応表

CRUD HTTPメソッド
C (Create) PUT
R (Read) GET
U (Update) POST
D (Delete) DELETE

多分こんな感じだと思います。

ただし、PATCHメソッドの説明で以下のような記述があるので、CRUD操作に対するHTTPメソッドは必ずしも一対一で紐づけられないことは留意する必要があります。

PATCH は CRUD に見られる "update" の概念にやや類似しています(一般的に、 HTTP は CRUD とは異なり、両者は混同するべきではありません)。

参考

HTTP リクエストメソッド - HTTP | MDN

export default

はじめに

例えばReactコンポーネントなどで、以下のように関数コンポーネントを定義することがあると思います。

export default function MyComponent() {
}

正直このexport defaultが何なのかよくわかっていなかったので、色々調べてみました。

結論

importする際に、{}がいるかいらないか、というのが1番わかりやすい違いです。

解説

こちらを読むのが1番早いです。
ただし、export defaultは使わないほうがいいという考え方もあるようなので、チームで統一したやり方があればいいってことなんでしょうかね。

参考

export - JavaScript | MDN

なぜ default export を使うべきではないのか? - LINE ENGINEERING

export defaultってなんだろう - Qiita

useStateのsetState()は非同期

はじめに

Reactを使用している方なら以下のようなコードは数え切れないほどに書いていることでしょう。

const [state, setState] = useState(0);

今回は、useState()から返されるステート更新用関数は非同期で実行される、という点について書いていきます。  

実験

以下のコードで試してみましょう。

  const [count, setCount] = useState(0);

  const onClick = () => { 
    setCount(count + 1);
    console.log(count); // 最初にクリックしたときは「0」が出力される
  }

  return <div>
    <div>{count}</div>
    <button onClick={onClick}>increment!</button>
  </div>

上記の例を見ても分かる通り、setCount(count + 1)が実行されても、直後にcountが更新されていないことがわかります。

さらに、例えば以下のようにdoubleCountUpがあるとしましょう。

  const doubleCountUp = () => {
    setCount(count + 1);
    setCount(count + 1);
  }

上記のdoubleCountUpが実行されたとしても、再レンダー後にはcountは1しか増えません。

解決案

以下のように修正することで、再レンダー後に期待した結果が得られるようになります。

  const doubleCountUp = () => {
    setCount(previous => previous + 1);
    setCount(previous => previous + 1);
  }

なぜ

なぜsetStateが非同期に実行されるかを説明しておきます。
仮に同期的に実行されるとすると、setState()の呼び出しごとにコンポーネントの再レンダーが発生してしまい、パフォーマンスが非常に悪くなってしまいます。   そのため、ReactsetStateをまとめて処理することで再レンダーを最小限に留めています。  

参考

What’s with functions inside setState? | by nashe omirro | Oct, 2021 | Medium