TECH-MICCHON.jar

Scalaを中心に技術的な話題を書きます。

ブログ移転しました

GitHub でホストする方式に変えたので、次のサイトに移転しました。

3tty0n.github.io

Hexo という静的サイトジェネレータを使っています。おしゃれなデザインも結構あるし何より GitHub で管理が出来るのでとても楽。次からそっちの方に更新していきます。

IntelliJ IDEA のヒープサイズを増やし快適に動作させる方法

概要

タイトルの通りです。IntelliJ IDEA を2年ほど使ってきましたが、この方法は全く知りませんでした。 IntelliJ IDEA はもともと与えられるヒープサイズが小さく設定されています。 したがって、ヒープサイズを多く与えることによって IntelliJ IDEA の動作をより快適にすることが出来ます。

元記事

IntelliJ IDEAのヒープサイズを増やす

この記事を見ながらやるとちゃんと設定出来ると思います。

やり方のまとめ

IntelliJ IDEAのバージョンを確認

  • 2017年6月現在最新のバージョンは IntelliJ IDEA 2017 1.4

idea.vmoptions を編集

macOS 環境の場合

まず次のコマンドを実行し、 idea.vmoptions を編集します。

$ vim $HOME/Library/Preferences/IntelliJIdea2017.1/idea.vmoptions

例えばヒープサイズを2GBにしたい場合、以下の内容を記述します。

-Xms2048m
-Xmx2048m

試してみて

これを試してみた結果、補完と起動が早くなった気がします!! おそらく IntelliJ 以外の JetBrains IDE を使っている人(たとえば PyCharm とか)にも有効だと思うので、皆さんも是非試してみてください。

株式会社ドワンゴでのインターンを終了しました

2017年3月30日付けで株式会社ドワンゴを退職しました。自分はインターンアルバイトとして入社したので、正確にはインターンを終了したということになるのでしょうか。

最初は右も左もわからない状態でしたが、メンターさんたちが根気強く支えてくれたお陰でここまで長い期間取り組めたのだと思います。この場を借りて改めてお礼申し上げます。

さて、せっかくなのでドワンゴでの思い出や取り組んできたことについて綴っていこうと思います。

思い出

2016年8月の入社から8ヶ月、主に Scala と playframework で課金系のシステムを作るお仕事をしていました。最後は新しいプロジェクトの立ち上げにも関わったりしました。

また、Scala 本体や akka とかにコミットしている方が同じフロアにいて席も年齢も近かったので仲良くなれたりとか、 scalaz コミッターのあの方がいらっしゃってランチで交流できたりするのがまた面白いところでした。

労働時間

ドワンゴはフレックス制です。私のチームは完全フレックスだったので、急なスケジュール変更にも対応できすごく助かりました。

大学の講義をこなしながらだったのでこれはとてもありがたかったです。

美容室と整体

ドワンゴには美容室と整体があります。

僕は美容室を何回か利用しました。インターン生でも使えるのでありがたかったのと、勤務時間中に行けるのでコーディングしながら髪を切ってもらえました。

また、表参道の一流の美容師が来てくれるので、結構いい感じに切ってもらえます。

ランチ

銀座はランチがとても美味しいです。色々なところに行きましたが、次のお店がおすすめです。

  • 牛庵
    • ここは最高級のお肉が1000円で食べれるから本当にすごい。最高。

取り組んだこと

入社して最初の頃は管理ツール用の API を作っていました。DDD の D の字も分からなかったのでコードを追うのにとても苦労しましたが、DDD の青い本を買って読んだり、先輩に色々聞いたりしてなんとか身につけました。

あと、インターン生である自分にもレビュアーをやらせていただいたのはとてもいい経験でした。今まで人に見てもらうことしかできなかったので、やってみて人のコードを採点するというのは結構勉強になるなぁと感じました。

その後は、バックログからタスクをもらってこなし、最後はプロジェクトの立ち上げにも関われました。特に、一からバックエンド部分の設計をやれたのはとてもいい経験になりました。

OSS

ドワンゴでは勤務時間中にもある程度は OSS 活動をしてもよいということになっています。なので、業務中に気づいたことがあったら、色々なプロダクトに PR を送ったりしてました。 特に playframework に PR 送ってマージされたときがハイライトでした。

github.com

他には、scalafx という javafxScala ラッパーライブラリの sbt をアップデートしたり、breeze という数値計算ライブラリの build.sbt を整備したりしました。

あとは自分で sbt プラグインを書いたりと、色々やってきたかなーと思います。

github.com

最後に

まだまだやっていきたい気持ちはあるのですが、ラボ生活がはじまるとスケジュールを合わせるのがちょっとむずかしくなるということもあって、キリの良いところで終了となりました。

自分は大学院に進学する予定なので就活はまだ先ですが、そのときは関係者の皆様にまたお世話になるかと思います。よろしくお願いします。

ほしいものリスト

来月から無職(?)なので、よろしくお願いします。

http://amzn.asia/3ArPBpP

mintedというLaTeXでシンタックスハイライトが出来るパッケージを導入する

導入方法

minted とは latexシンタックスハイライトをしてくれるパッケージです。 以下はその導入方法の説明になります。

実行環境は

です。

インストール手順

  • sudo easy_install Pygments
  • https://www.ctan.org/pkg/minted から zip をダウンロードし make
  • make したら minted.styminted1.sty 出来る。それを texmf の中に入れる

minted の使い方

  • texファイルをコンパイルするときに -shell-escape オプションを付ける
  • texlive2015の場合は \usepackage[cache=false]{minted} とする
    • これはtexlive2016だと不要らしい

サンプルソースは以下のようになります。

\documentclass{jsarticle}
\chardef\pdf@shellescape=\@ne
\usepackage{minted}
\begin{document}
\begin{minted}{c}
#include<stdio.h>
int main(void){
  printf("Hello World!\n");
  return 0;
}
\end{minted}
\end{document}

東工大ポータルにSeleniumでブラウザから自動ログイン

東工大ポータルにSeleniumで自動ログイン

自分の大学のポータルサイトには二段階認証が付いており、それは一時的にtokenを発行するようなものではなく、よくネットバンキングで使われるようなマトリックス認証である。

セキュリティ的には幾分強くなるのだが、ちょっと使い勝手は悪い(Google二段階認証を使わせてくれないだろうか…)。

そこで、ちょっと不便な現状を打破すべく自動ログインツールを作ろうと思った。

一方、「東工大ポータル 自動ログイン」でぐぐってみると結構な数の「ログインツールつくってみた」系の記事がヒットする。 じゃあこれでは二番煎じなのじゃ…と思ったけど、既存のツールはだいたい

の二種類しかなさそうというのが、ちょっと調べてみて分かった。

そこで今回作ったのはブラウザを操作して自動ログインするツールである。

github.com

追記

より安全な方法に実装を変更し、それにともなって使い方の章を修正しました。

使い方

拙い英語で README.md に記したのだが、大事なことなのでここでもまた説明する。

準備

以下のフローでこのスクリプトを動かす環境ができる。

  • firefox を用意する
  • $ make
  • $ make build.<your os>
    • your os というのは macox, linux64, win64 である。

ログイン(追記)

以前の方法ではリポジトリに直にパスワードを置くためセキュリティに問題があった。 ここで、pitというライブラリを使い、設定ファイルを外に置くことにした。 設定の方法は、make したあとに

$ vi ~/.pit/default.yaml
titech:
  usr_name: YOUR_USER_NAME
  usr_password: YOUR_PASSWORD
  usr_matrix: ['xxxxxxx', 'xxxxxxx', 'xxxxxxx', 'xxxxxxx', 'xxxxxxx', 'xxxxxxx', 'xxxxxxx', 'xxxxxxx', 'xxxxxxx', 'xxxxxxx']

default.yaml を編集すればOK。 usr_matrix はAからJまでの列にあるアルファベットを配列でflfejfewみたいに記入する。

ログインする

  • $ make login

これでOK。

実装

Selenium-webdriverを使って簡単なスクリプトRuby で書いてみた。簡単に説明していく。

@driver = Selenium::WebDriver.for :firefox

これでブラウザを操作するドライバーインスタンスを作っている。これがSeleniumスクレイピングするときのすべての始まり。

以下は、細々とした実装になってしまった。

@driver.get 'https://portal.nap.gsic.titech.ac.jp/GetAccess/Login?Template=userpass_key&AUTHMETHOD=UserPassword'
usr_name = @driver.find_element(:name, 'usr_name')
usr_name.send_keys(@usr_name)
usr_pass = @driver.find_element(:name, 'usr_password')
usr_pass.send_keys(@usr_password)
@driver.find_element(:name, 'OK').click

sleep 3

ここで Basic 認証を突破している。

@driver.find_element(:name, 'usr_name') でIDを入力するelementを見つけてきて、そこにusr_nameを入力。

passwordの部分も同じである。

sleep 3 は認証してレスポンスが返ってくるまで時間がかかってしまい、waitしないとエラーになるため入れいている。

def get_password_value_from_message(message)
  @usr_matrix[message[0]][message[1] - 1]
end

def get_message_value_from_xpath(element)
  [element.text[1], element.text[3].to_i]
end

xpath_list = [
  '/html/body/center[3]/form/table/tbody/tr/td/table/tbody/tr[5]/th[1]',
  '/html/body/center[3]/form/table/tbody/tr/td/table/tbody/tr[6]/th[1]',
  '/html/body/center[3]/form/table/tbody/tr/td/table/tbody/tr[7]/th[1]'
]

pass_list = [
  @driver.find_element(:name, 'message3'),
  @driver.find_element(:name, 'message4'),
  @driver.find_element(:name, 'message5')
]

message_value = xpath_list.map { |e|
  get_message_value_from_xpath(@driver.find_element(:xpath, e))
}

pass_list.zip(message_value).map { |pass, message|
  pass.send_keys(get_password_value_from_message(message))
}

@driver.find_element(:name, 'OK').click

これは、xpathマトリックス認証に必要な要素を見つけて来て、そこから必要なアルファベットを取得している。 この部分が一番実装していて面倒だった。

最後に

東工大ポータルのログインツールは色々調べてみたので、あとでまとめてみても面白そうな気がした。

sbt plugin の作り方 - 実際の plugin を用いて解説 -

概要

sbt plugin の作り方をこちら

github.com

のコードを使いながらざっくり解説していきます。

sbt plugin を作る

sbt plugin はいくつかの Key に対してその振る舞いを記述していく、というスタイルで実装していきます。 振る舞いとは、例えば

  • Groovy など ScalaJava 以外のソースをコンパイルする
  • プロジェクトを jar に固めてデプロイする

などがあると思います。

sbt plugin はおおまかに分けて

  • Key
  • Task
  • projectSettings

という三つの要素があり、plugin 開発者はそれぞれを実装していく必要があります。

そのテンプレートは次のようになります。

import sbt._
import Keys._

object SimplePlugin extends AutoPlugin {

  object autoImport {
    /** implement your keys */
    ???
  }

  import autoImport._

  override def trigger: PluginTrigger = allRequirements

  override val projectSettings = ???

  lazy val yourTask = Def.task { 
    /** Implement your task(s) */
    ??? 
  }
}

Key

Key には以下の三種類があります。

  • settingKey: 属性、可変の値
  • taskKey: 実際の振る舞い
  • inputKey: taskKey でコマンドライン引数を受け取りたい場合の振る舞い

今回は settingKeytaskKey を使いました。

実際に定義したいのは次の4つです。

  • jflex ファイル *.flex の場所
  • 生成するファイル *.scala の場所
  • 実際に生成する振る舞い
  • その他設定

しがたって、以下のように実装しました。

 object autoImport {
    lazy val jflexSourceDirectory = settingKey[File]("jflex-source-directory")
    lazy val jflexOutputDirectory = settingKey[File]("jflex-output-directory")
    lazy val toolConfiguration = settingKey[JFlexToolConfiguration]("jflex-tool-configuration")
    lazy val pluginConfiguration = settingKey[PluginConfiguration]("jflex-plugin-configuration")
    lazy val jflexGenerateWithCompille = settingKey[Boolean]("jflex-with-compile")
    lazy val jflexSources = taskKey[Seq[File]]("jflex-sources")
    lazy val jflexGenerate = taskKey[Unit]("jflex-generate")
  }

Task

Key を定義したら次は Task を定義します。Task とは「実際の動作」であり、jflex-scala-plugin では

  • jflex API を叩いて *.flex ファイルを生成する

という振る舞いが想定されます。したがって、次のように実装しました。

lazy val jflexGeneratorTask: Def.Initialize[Task[Unit]] = Def.task {
    generateWithJFlex(
      jflexSources.value,
      jflexOutputDirectory.value,
      toolConfiguration.value,
      pluginConfiguration.value,
      streams.value.log
    )
  }

  private[this] def generateWithJFlex(
    srcDir: Seq[File],
    target: File,
    tool: JFlexToolConfiguration,
    options: PluginConfiguration,
    log: Logger
  ): Unit = {
    target.mkdirs()

    log.info(s"JFlex: Using JFlex version ${Main.version} to generate source files.")
    Options.dot = tool.dot
    Options.verbose = tool.verbose
    Options.dump = tool.dump
    Options.setDir(target.getPath)
    Options.emitScala = tool.emitScala

    val grammars = (srcDir ** ("*" + options.grammarSuffix)).get
    log.info(s"JFlex: Generating source files for ${grammars.size} grammars.")

    grammars.foreach { g =>
      Main.generate(g)
      log.info(s"JFlex: Grammar file ${g.getPath} detected.")
    }
  }

projectSettings

ここには、デフォルトの挙動(初期値)を記述していきます。

sbt-jflex-scala の場合、次のような初期値を設定しました。

  • *.flex ファイルはデフォルトで src/main/flex にする
  • 生成される *.scala ファイルはデフォルトで src/main/scala/flex にする
  • コンパイル時の自動生成はデフォルトではオフ

したがって、次のような実装になりました。

  override val projectSettings: Seq[Setting[_]] = Seq(
    jflexSourceDirectory := sourceDirectory.value / "main" / "flex",
    jflexOutputDirectory := sourceDirectory.value / "main" / "scala" / "flex",
    toolConfiguration := JFlexToolConfiguration(),
    pluginConfiguration := PluginConfiguration(),
    jflexSources := (jflexSourceDirectory.value ** "*.flex").get,
    jflexGenerate := jflexGeneratorTask.value,
    unmanagedSourceDirectories in Compile += jflexSourceDirectory.value,
    jflexGenerateWithCompile := false
  ) ++ Seq(
    compile := {
      if (jflexGenerateWithCompile.value)
        (compile in Compile).dependsOn(jflexGenerate).value
      else
        (compile in Compile).value
      }
  )

これで、sbt plugin のパーツが整ったので、あとはテンプレート部分を埋めるだけです。

全体像はこちらを参照してください。

参考

jflex-scala の sbt plugin を作った話

JFlex とは

JFlex とは Java で書かれた構文解析器を生成するためのライブラリで、Javaのコードを生成します。

sbt-jflex-scala を作った動機

JFlex の fork の中で jflex-scala というものがあり、これは Scala のコードを生成してくれます。

github.com

これを sbt 上で利用するための sbt プラグインはいくつかあるのですが、どれもあまりメンテされておらず、動作しないため、この際新しく作り直しました。

3tty0n/sbt-jflex-scalaホスティングしてあります。

github.com

使い方

使い方は単純で

  • project/plugins.sbt に次の記述を追加
 addSbtPlugin("com.github.3tty0n" % "sbt-jflex-scala" % "0.1.1")
  • *.flex ファイルを src/main/flex に置く
  • $ sbt jflexGenerate

Yylex.scala が生成されます。

オプションで

jflexWithComple := true

とすると、コンパイル時に Yylex.scala を自動生成してくれます。

最後に

イマイチ需要はわからないけど、構文解析する人にとってはちょっと便利になるかもしれません。

この次は sbt plugin の作り方をまとめてみたり、 Elm の話もできたら良いと思っています。