bussorenre Laboratory

hoge piyo foo bar

Intelli J Idea でScalaを書く環境を整えてく(自分用)

業務用ということで、会社から Inteli J Idea を支給してもらった。この機会にぜひとも乗りこなしたい。

Emacs バインドをある程度使えるようにする

Emacs使いのための IntelliJ IDEAキーマップ チートシート を参考にする。

Emacs+ Patched というプラグインを入れ、 Preferences -> Keymap で Emacs+ を選択し、Duplicate... でコピーを作成

Preferences -> Appearance & Behavior -> Presentation Assistant で、Main keymap に作成したコピーを指定

変更 キーバインド アクション 追加 Ctrl+X, Ctrl+B Switcher

PlantUML

IntelliJ IDEAでPlantUMLを書く

PlantUML でドキュメントを書いているので、同じくプラグインをぶっこむ。

初めて入れてみたけどくっそ便利すぎて今までの人生は何だったのか感

Scala における Unit型と副作用

C系とか Java 系みたいな、手続き型には無い(無くはないけどそんなに重要視されていない)概念に 作用と副作用がある。

関数型言語では、プログラムは値を返す存在とみなされる。

Programming in Scala においては 3.5 あたりに

まずは、val、イミュータブルオブジェクト、副作用のないメソッドを優先させ、それらで出来る限りやってみる。 明確なニーズと正当化できる理由がある時に限り、var、ミュータブルオブジェクト、副作用のあるメソッドを使う

と書いてある。

副作用とはどういうことか。

例えば「標準出力にHello world を出力する」という仕様に対しては、前回書いたHelloworld だと

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

こうなっており、引数を受け取って結果(作用)を返していない(=副作用しか無い)メソッドになっている。 こういうメソッドにはUnit型が使われる。

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バイト記法のため

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

参考にした記事とか