bussorenre Laboratory

hoge piyo foo bar

Hello world in Scala

どんな事もまずは世界に挨拶することから始まる。

Scala で 雑に Hello World を書くとこうなる。

object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("Hello, Scala world!")
  }
}

基本的にScalaJava class コードに変換されるので、JVM の制約を多少なりとも受ける。例えば、main(args: Array[String]) 型のメソッドを持つクラスをエントリーポイントに持つ等。

型定義は後置。Swift やgo も後置なので違和感はない。

Unit 型 というのは副作用のみを扱う関数(メソッド??)に付けられる型。このへんはまだ良くわかってないのでわかってきたタイミングで書く。

println, Array, String, Unit はどこで定義されて来ているのか?

Scalaパッケージメモ(Hishidama's Scala package/import Memo) によると、

名前 用途 備考
scala._ Scalaの基本クラス
scala.Predef._ 暗黙に使用できる関数が定義されているシングルトンオブジェクト Javaのstaticインポートに相当する方式でインポートされる。Predefに定義されているメソッドを関数として(オブジェクト名の指定なしで)使えるようになる。
java.lang._ Javaの基本クラス

が、自動的に(暗黙的に)import されていて、利用できる。

ScalaStandard Library によると、scala.Predef は

package scala
object Predef {

  // classOf ---------------------------------------------------------

  /** Returns the runtime representation of a class type. */
  def classOf[T]: Class[T] = null
   // this is a dummy, classOf is handled by compiler.

  // Standard type aliases ---------------------------------------------

  type String    = java.lang.String
  type Class[T]  = java.lang.Class[T]

  // 中略
  def println() = Console.println()
  def println(x: Any) = Console.println(x)

みたいな感じで記述されている。

$ scala helloworld.scala

で実行できる。スクリプト言語みたいな動作をする(多分実際には内部的にclass ファイルを作っているとは思うが)

クラスコードに変換して実行するには

# scalac helloworld.scala ではなく scala.helloworld.scala になってたのを修正しました
scalac helloworld.scala
scala HelloWorld

(雑談) Scala はじめました

夏の暑い時期に冷やし中華を始めるラーメン屋の如く、私もScala をはじめました。

最低限の知識だけで、可能な限りJVMの世界を避けてきたのですが、ついに通らずにはいられなくなったのですが、幸い 素のJava6 とかじゃなくて、scala の世界で戦えるのでそれはラッキーだったかも。

とりあえず Scala スケーラブルプログラミング(Programming in Scala)をちょくちょく読んでます。 https://www.amazon.co.jp/Programming-Scala-Comprehensive-Step-Step-ebook/dp/B01EX49FOU/ref=sr_1_1?ie=UTF8&qid=1533103722&sr=8-1&keywords=scala+in+programming

元々プロダクションでruby を書いてましたが、やっぱり言語も進化する。2000年代に生まれている言語のほうが洗練されてる。

まだ全然読み切れていないですが、scala を経てSwift の良さも更に噛み締めてます。

ということで、しばらくscala マンになります。わーい

Rails の開発環境をDocker で構築してて、Rails s は出来るのにRails cとかr が出来ない問題に遭遇した

未だに根本原因は解決していない。

ruby 2.5.1 bundler 1.6.2, 1.6.3 rails 5.1.0

blog.freedom-man.com

解決策としては、この解決策でなんとかなったのだが、 Rails server は動いて、Rails console は動かないというのは、非常に不思議。

Rails server と Rails console で呼び出しているロードパス経路が違うっぽいので、そのへんに原因があるのかなーとも思ったり、 bundler は昔から色々と不思議なことがおおいから、そっちのほうに原因があるのか?確かに似たようなissue 立ってるし。

とも思ったり。

windows subsystem for Linux で 困ったこととその解決法

「この記事は個人の見解であり、所属する組織の公式見解ではありません」

5月8日、4月には結局間に合わなかった Windows 10 Redstone 4 のアップデートが配信されました。Redstone におけるメジャーバージョンアップは従来のService Pack 並の大きな変更ですが、その中でも特に WSL, Windows subsystem for Linux における機能拡張に着目して、WSL で どこまで出来そうか確認します。

Redstone 4 における最も基本的でかつ重要な変更として、パーミッション管理が多少改善された事にあると思っていています。特に(visual studio Code 等でコードを編集するために)、WIndows 側のディレクトリにローカルリポジトリをおいていた場合、今までは ユーザー root, グループ root, パーミッション777  になっていたと思います。これが少しはましになりそうです。

今回利用するのは WSL の中でも Ubuntu 18.04 を利用します。いつになったら RedHat がリリースされるのか。笑

Windows Update を手動チェックし、更新をインストールする

Windows をゲーミング用途以外で触るのは本当に久しぶりです。 早速 Windows Update をかけます。時々アップデートを無視してしまうことがあるので、Cortana で「Windows Update」 と入力し、強制的にアップデートをかけます。ついでにWindows Defender の定義ファイルも更新しましょうね~。結構時間かかります。

終了すると必ず再起動を求められるのでお忘れずに。

古いWSL環境を削除する

必ず CMD.exe から管理者モードで 以下のコマンドを実行します

lxrun /uninstall /full /y

これにより、現存するUbuntu 環境が消えます。もしエラーが実行できない場合は、よくわかりません(※ なんでエラーになったのかわからないのですが、特に気にせず次のステップにすすめました)。 なので、無視して次に進めて大丈夫です

Windows Store から Ubuntu 18.04 をインストールし、普通に起動します。 ユーザー名、パスワードを設定できるので設定します。

umask の設定をする

まず、デフォルトの状態でディレクトリを作ると、パーミッションが 777 になっていると思います。(なっていないならこのステップは無視) vim かなにかで .profile を開き、以下の行のコメントを解除します

#umask 022

コメントアウトしたら source .profile で再度読み込みを

windows 管理下のディスクにLinuxパーミッションを付与できるようにする

Windows が採用しているファイルフォーマットNTFSには、Linuxパーミッションを保存することが出来ないので、アダプターとなるファイルシステム drvfs にメタデータを付与するオプションを付けて、再度マウントする

# C がすでにマウントされているなら、一度アンマウントする
$ sudo umount /mnt/c

# metadata オプションをつけて再度マウントする
$ sudo mkdir /mnt/c
$ sudo mount -t drvfs C: /mnt/c -o metadata

これにより、windows 側のフォルダも、パーミッションが付与できるようになる。やったぜ。 ところがこれ、大きな落とし穴があり、windows 側でファイルを更新すると、なんとパーミッション等のメタデータが破壊されてしまう。なんでやねん!!!笑

というわけで、マウント時にデフォルト値を設定してあげることで、windows 側でファイルをいじっても元通りっぽいパーミッションになることができる。

$ sudo mount -t drvfs C: /mnt/c -o metadata,uid=1001,gid=1001,umask=22,fmask=111

↑の例だとC 全体をマウントしているので、workspace などのみをマウントして利用するのが安全そう

$ sudo mount -t drvfs 'C:\workspace' /mnt/workspace -o metadata,uid=1001,gid=1001,umask=22,fmask=111

その他 windows 環境での作業改善をする

個人的にはMac のctrlキーが Aの左にあるの、すごい気に入っていたので、ctrlキーを A の左のキーに割り当てます。windows 標準JISキーボードは大体左にcapslock があるんじゃないでしょうか。 フリーソフトでいじることも可能ですが、変なソフト入れたくなかったので直接レジストリをいじります。

cortana に regedit.exe と入力します。

細かい方法は参考記事に載っていますが、capslock を 左ctrlに割り当てるには

  • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layoutを開く。
  • 右クリックして→「新規」→「バイナリ値」を作成して、名前を「Scancode Map」にする。
  • Scancode Mapを開く。
  • 以下のように値を設定する。
0000 0000 0000 0000 
0200 0000 1D00 3a00 
0000 0000

で実現できます。1d00 というのは、ctrl キー 0x1d のリトルエンディアン2バイト記法のため

さて、これで多少は使えるようになりました。 次は実際に快活環境を入れて、開発動かしてみるか……

参考にした記事とか

コンテキストスイッチにどうやって立ち向かうか

「この記事は個人の見解であり、所属する組織の公式見解ではありません」

またこいつは炎上しそうな記事を書いて……と自分で思いましたが、真剣に悩んでいるので人の目に触れる所に置いて意見を貰うことにしました。

本来、コンテキストスイッチとはCPUが複数プロセスを並行して動かしているように見せるために、CPUやメモリの状態を入れ替え差し替えする機能の事を指しますが、この記事では、1人の人間が、文脈の異なるの業務を並行的にこなさなければならない状況で発生する、脳内での業務の切り替え の事を意味します。

前提のお話

コンテキストスイッチにはコストが掛かる

まず、前提として、コンテキストスイッチには、スイッチングコストがかかります。

例えば、1人の人間(P)が100 の業務量をこなせるとします。(単位はまぁ概念的なものなので適当に想像してくれ)

上司は部下にあれこれ仕事を割り振るのですが、その中でも、A-E の業務に着目し、業務量を見積もると、だいたい以下のような感じでした。

A = 70
B = 40
C = 30
D = 20
E = 10

この時、P さんに任せる仕事として最適なのは どういう組み合わせでしょうか?

単純に計算すると、 A + C = 100 だったり、 B + C + D + E = 100 だったりするので、そういう組み合わせが良いと思うかもしれません。

しかし、ここには「人間はコンテキストスイッチングに多少なりとも時間がかかる」という条件が考慮されていません。

例えば、月から金まで働くとして、月火水 は A という業務に着手し、木金は C という業務に着手する。その間に業務の切り替え(コンテキストスイッチ)の発生回数は2回で、(A からC への切り替えと、C からAの切り替え。厳密にはC からA は土日を挟むので発生しないかもしれないがそれはさておき) コンテキストスイッチにだいたい1の業務量を要する。

とすると、A とC のタスクをアサインされている人の業務量は 70 + 30 + 2 = 102 になるわけです。ちょっと残業ですね

では、B + C + D + E = 100 の業務を持つ人が 1回のコンテキストスイッチにかかる業務量を1 として、必ずB, C, D, E の順番で業務を実行していくとどうなるか?というと、業務量は105 になります。

じゃぁ実際に105か?と言われると、そんなことはないです。

例えばBの仕事を実行している時に急遽Eの仕事のクライアントから緊急の電話が掛かってきたりすると、一旦Bの手を止めてEの頭に切り替えなければなりません。要件がすめばまたBに頭を戻せば良いわけですが、この時コンテキストスイッチが2回発生しています。

業務量が更に増え、107 になりました。こうして、残業が増えていくんだなー。

大きな集中力が必要な業務

アートの製作や、複雑なロジックの実装、MVPの検討など、非常に高度な集中力を要する業務というのが存在します。例えば40 の「集中力が必要な業務」の進行中に、だいたい20まで進行したところで、上記のようなクライアントからの緊急の電話等でコンテキストスイッチが発生すると、頭がリセットされて最悪0 からになるかもしれません。0までいかなくても、「で、ええっと何の話をしたんだっけ?ああそうそう」というロスタイムが生じる経験は誰にでもあると思います。同じ議論をやり直しているかもしれない。

集中力が必要な業務中に、コンテキストスイッチが発生しないようにする工夫は必須です。

コンテキストスイッチが発生しまくる現場では、こうした集中力が必要な仕事はなかなか手がつけれません。無理です。

みんな1人月として業務を振ってくる

例えば、A という業務と B という業務、それぞれ別のチームの仕事だったとします。B のチームの人からは、Aのチーム/仕事が見えないので、ついつい P さんに1人月分(=100)の仕事を振ってしまいがちです。

同じことがA でも発生します。例えば、Aチームでは、納期に間に合うか間に合わないかくらいのギリギリなスケジュールで動いていて、「P さん、ちょっとこのチケット持ってもらえませんか?」みたいな会話が発生したりします。まだB に比較的余裕があって「ああ、OK じゃぁA のほう頑張ってくれ」とコミュニケーションできればいいですが、「え、それは困るBもパツってる」とかになってくると、しんどくなります。

そしてコレはただの経験則ですが、だいたいしんどい次期は重複するので、Aがパツってる時にB が余裕ある という事はあんまりありません。パツってる時はだいたい緊急度が高い会話をする必要が多く、それだけコンテキストスイッチも発生し、雪だるま式に業務量が膨張します。

自発的に発生するコンテキストスイッチ

所謂生理現象です。トイレ行きたいとか眠いとか腹減ったとか、そういう生理的欲求による中断の他に、僕は勝手に小さなフラッシュバックと呼んでいるのですが、何か特定の事象を見て、それに興味が奪われたり、忘れていた何かを思い出してしまったりする現象があります。

外部からの割り込み以外にも、自分の中で発生する割り込みも存在します。これも経験則なので根拠微妙ですが、精神的なダメージを負っている時によく発生するイメージがあります。

コンテキストスイッチにどうやって立ち向かうか

そもそも複数業務をアサインしないようにお願いする

上司と相談出来る環境、そして上司がそれを納得して受け入れてくれる環境なら見えてくる選択肢です。 が、だいたい1人の人間に複数種類の業務がアサインされている時はもう上司の時点でパツってるので、この方法が通ることはまずありえません。

もしどうしても、1人の人間に複数タスクをアサインしなきゃいけない時、最も効果的だなって思っているのは 80:20 くらいで、それ以外のアサイン方法でまともなのを知りません。

業務時間を固定する

例えば、80:20 で分割した場合、20のほうの業務を必ず金曜日に行う 等の合意が取れていれば、コンテキストスイッチの発生回数は極端に減ります。 さっきも書きましたが、土日が休みな場合コンテキストスイッチは土日に行われるので、101 くらいの業務量で済みます。

割り込みを回避する

特に集中力を要する仕事で有効な方法だと思っていて、誰からも声を掛けられない場所に引きこもり、チャットツールも閉じる というのが有効だと思っています。人が減りだす 20:00 - 24:00 のオフィスであったり、世間が寝静まった1:00 - 5:00 の間に最も集中力が高まることを感じるのもこれかなと思っていて、理由は割り込み回数が極端に少ないからです。

集中する部屋 みたいなのが固定デスクとは別に設けられているオフィスは良いと思うのですが、そうでなかったり、全域フリーアドレス とかになってくるとものごっつしんどいですね。

自分はどうすればいいのか

さて、じゃぁ今自分がどうなっているかというと、A+B+C+D+E= 120 くらいになっています(限界量100) コンテキストスイッチは頻繁に発生するので、実感値としては200くらいです

さて、どうすれば良いのか。

そもそも複数業務をアサインさせないようにお願いする は既に実行済みですが、「A+B+C+D にはなるかも」って感じで、うーんそれでもまだ4あるのか辛いという状態。次に有効かなと思っているのが、「じゃぁ月曜日、火曜日休みで 土日出社という感じのフレックス制度になりませんか?」 という相談。これは明日試してみるが、多分、人事や総務的な観点からお断りされると思っていて厳しい。

自分の中で、業務時間を固定してその時間はそれ以外のことを一切しない という強い意志表示をする というのが、多分自分に出来る唯一のカードだな。と思っていて、今全力で冷徹になろうとしている。(スケジューラーブロックを完全にブロックして会議を打ち込まれるのを防ぐ等。)

他にどうすればいいのか。

「お前の頭が悪い」と言われたら「すみません」としか言えません。自分の頭の悪さはコントロール出来ないので………。お前が無能だからそういうアサインのされ方をされるんじゃないか?と言われたらぐうの音も出ませんが、無能が加速するのでできれば辞めてほしい所……。

他の人がどういう感じで仕事しているのか、えるちゃん以上に私、気になってます。

どうしてwebフレームワークに苦手意識を感じるのか

創作物(ドラマやアニメ)において、「この物語はフィクションです。登場する人物・団体・名称等は架空であり、実在のものとは関係ありません。」という注意書きが必ず記載されるのと同様に、個人ブログにおいても、必ず「この記事は個人の見解であり、所属する組織の公式見解ではありません」という但し書きを書く必要が出てきたので、鬱陶しいですが毎回書きます。ご容赦を。

「この記事は個人の見解であり、所属する組織の公式見解ではありません」

私は、例えばRuby on Rails のような強力なwebフレームワークが非常に苦手で、なんでこんなにやりづらいんだろう?と思っていた。フレームワークを入れたは良いが、実現したいソフトウェアをいざ実装するぞとなったら、まるで手が動かなくなる事が多い。その原因がさっぱり見えていなかったのだがようやく分かってきたので書く。

1. そもそもちゃんとドメインモデルを構築できていない。

フレームワークどうこういう以前の問題として、私個人のモデル設計力が低い。 とにかくコレに尽きると思う。特に学生の時は深いことをさっぱり考えずに「とりあえず実装するか」とコードをしっちゃかめっちゃかに書きなぐって「とりあえず動いたからリリースしようぜ」というのが許された。(許されたわけではないと思うが、基本的に設計から実装からリリースまで全部1人だったし、趣味の園長のようなプロダクトなので、困るのは自分くらいだった)

なので、オブジェクト間の依存関係とか全然考慮されておらず(いや、多少は考慮していたが、完成度の低いモデルで)酷い設計/実装だった

2. フレームワークの学習コストの見積もりが甘い

Zendにせよ、RoR にせよ、Django にせよ、所謂「重い」と言われるフレームワークはとにかく、何人もの優秀な技術者の知恵と努力が何年も積み重なったもので、一介の素人がちょっとドキュメントを読んだだけで理解出来るものではない。(ちょっとドキュメントを読んだだけで全てが分かるのなら、世界は優秀な技術者を必要としない)

とにかく学習コストが高い。学習コストが高いと嘆いているうちは、まだ自分の道具になっていないという事だし、道具に振り回されて疲れ果てることになる。既に道具として使いこなしている先輩方から「これはこうしたほうがいいんじゃね?」と言われても、何を言われているのかわからないので、反論が出来ない。

また、上述の通り、ドメインモデルがしっかりしていないので、「このフレームワークではこうするんだ」というフレームワークの思想が優位に立ち、本当にすべき実装が見えていない。というのもある。

という事を青DDD, 赤DDDを読みながら思った。

エリック・エヴァンスのドメイン駆動設計

実践ドメイン駆動設計

青DDD は読むの物凄くしんどかった。オススメしない。赤DDD は DDD についてある程度知識がある前提で進むので、青DDD の要約スライドを見て挑むのが一番学習効率が良さそう。