ソフトウェアデザイン2016年12月号

会社の同僚であり、若者であり、エモジニアである@todokr文字コード特集の記事を執筆したとのことでゲットしてみました。

第2特集ということではありますが、文字コードの基礎からHTML、JavaRubyMySQLでの文字コードの扱いについて解説されています(RubyMySQLについてはとみたまさひろさんが執筆されています)。

最近はWeb開発に携わっていても文字化けなどに悩まされることは減ってきたような気がしますが、インターネット上にはまだまだShift_JISEUC-JPといった文字コードを使用しているサイトも多数存在しますし、一方で絵文字の扱いといった新たなトピックも出てきています。そもそもWebとテキストは切っても切れない存在ですから、文字コードの基礎を押さえておくことはWebエンジニアにとって有益なことなのではないかと思います。

また、個人的には第1特集のNoSQLもさることながら、第3特集のITむかしばなしスペシャルが面白かったです。むかしといっても80年代〜90年代という、これを読んで懐かしくなるのはおそらくアラフォー以降の世代であろうという真の昔話です。この記事を現代の若者が読んで一体どのような感想を持つのだろうかというのはかなり気になるところなので是非若者に読んで欲しいという気持ちになりました。

紙媒体の雑誌を手に取ることは最近本当に少なくなりましたが、やはりオンラインの情報だけだと自分の興味ある分野しか見に行かなくなりがちです。専門分野外の情報のインプットのためにも、バリエーション豊かな記事が掲載されており気軽に読むことのできる雑誌はいいものだと改めて感じました。

Scala 2.12に対応したScalatra 2.5がリリースされました

ここしばらく作業をしていたScalatra 2.5が先日無事リリースされました。

リリースノートは以下になります。

http://scalatra.org/2016/11/21/scalatra-2-5-released.html

今回のリリースはScala 2.12への対応とSwagger 2.0のサポートが大きなトピックになります。どちらも作業は自分がメインで進めさせていただきました。

Scala 2.12対応はScalatraが対応しないとGitBucketも上げられないという理由があったので積極的に取り組んだのですが、最終的には吉田さんや瀬良さんにいろいろ直していただきました。ありがとうございました。自分のScalatraでの活動は2014年のScala 2.11対応まで遡りますが、瀬良さんは継続的に活動されていますし、リリースのオペレーションなどでも貢献されていて凄いなぁと思います。

さて、Scalatraも気づけば2000スターを超えていますし、本も出ているのですが、その割には今いちメジャー感がないですね。なんでかわかりませんが…。

Scalatra in Action

Scalatra in Action

世間ではノンブロッキングだリアクティブだと言われていますが、実際のところServletで十分というケースも多いのではないでしょうか。また、運用のこなれたアプリケーションサーバを使いたいという要望もあるかもしれません。そういったケースであれば使い慣れたミドルウェアアーキテクチャの上で、言語としてのScalaの良さを活かすことができるScalatraは有力な選択肢になるのではないかと思います。

今後についてですが、Scalatraは開発リソースが貧弱な割にオプション的なモジュールが多くサポートやメンテナンスがきついので、Scalatra 2.6(もしくは3.0?)では重要度の低そうなモジュールの切り離しを進めていけるといいかなと思っています。

同僚が「それゆけ!ターミナル部」という連載を始めました

会社の同僚である@tanacasinoマイナビさんのギークロイドというメディアで「それゆけ!ターミナル部」という連載を始めました。

若干老害の入ったマーティン・シェルスキー先生が若干意識高めの若者タミ夫くんにターミナルのテクニックを教えていくというものです。隔週連載の予定とのことで、すでに第三回まで公開されています。

mynavi-agent.jp

mynavi-agent.jp

mynavi-agent.jp

最初は環境構築など基礎的なところからのスタートでしたが、第三回はシェルの展開など実用的な内容になってきています。自分もターミナル力低めなのでこれを読んで精進したいと思います。

続・AtomでMarkdownのアウトラインを表示する

以前こんな記事を書いたのですが…

takezoe.hatenablog.com

最近document-outlineというパッケージを発見しました。

atom.io

こちらはMarkdownの見出しをツリー状に階層化して表示してくれます。これこそ正に私の求めていたもの!!

f:id:takezoe:20161120124016p:plain

…と思ったのですが、どうやら行頭を#で開始していないと見出しだと認識してくれないようです。つまりこういうMarkdownだとダメ。

見出し1
========

見出し2
--------

まあ最初から気をつけて書いていれば問題ないかな。長文を書いているときは全体を見渡すためにアウトラインが欲しくなるのでこれを活用していきたいです。

市ヶ谷Geek★Nightで「Scalaによるタイプセーフなフロントエンド開発」という発表をしました

普段フロントエンド開発は若者に丸投げしているバックエンドおじさんですが、ここのところScala Warriorを開発するためにScala.jsを触っていたということもあり、お声がけいただいてScala.jsの紹介をさせていただきました。

ichigayageek.connpass.com

発表資料はこちらです。

www.slideshare.net

結論としてはありがちですが、フロントエンドまで全てをScala.jsで書くのではなく、APIサーバへのアクセスや複数APIのアグリゲーション、フロント用に加工する処理などをラップしたライブラリをサーバサイドのエンジニアが提供するために利用し、フロントからはそれを呼ぶだけにするという使い方がよいのではないかと思います。

ところで会場からの質問でScala.jsでコンパイルしたJavaScriptをインポート/エクスポートできるのか?といご質問があり、その場では「できない」と回答してしまったのですが、実は今年の10月にリリースされたばかりのScala.js 0.6.13からCommonJS形式でのインポート/エクスポートがサポートされていました。

www.scala-js.org

build.sbtに以下の設定を行っておくと@JSExportアノテーションでエクスポートしたクラスやオブジェクトが利用可能なCommonJSモジュールにパッケージングすることができます。

scalaJSModuleKind := ModuleKind.CommonJSModule

たとえばこんなクラスをScala.jsでコンパイルします。

import scala.scalajs.js
import js.annotation._

@ScalaJSDefined
@JSExport("HelloWorld")
class HelloWorld extends js.Object {
  def sayHello(name: String): String = s"Hello ${name}!"
}

するとJavaScriptからは以下のようにして使用することができます。

var test = require("./test-fastopt.js")

var helloWorld = new test.HelloWorld();
console.log(helloWorld.sayHello("Scala.js"));

逆に@JSImportアノテーションを使うとScala.jsでCommonJSモジュールを使うことができます。

import scala.scalajs.js
import js.annotation._

@js.native
@JSImport("./test-fastopt.js", "HelloWorld")
class HelloWorld extends js.Object {
  def sayHello(name: String): String = js.native
}

Scala.jsでコンパイルしたJavaScriptをCommonJSモジュールとしてエクスポートすることができるようになったことでScala.jsを既存のJavaScriptのエコシステムに組み込むことが可能になり、サーバサイドエンジニアが提供するライブラリをフロントから使用するという分担もスムーズに連携できるようになりますね。Scala.jsの活用の幅はより広がってきていると言えそうです!

Scala.js is awesome!!

GitBucket 4.6をリリースしました

Scalaで実装されたオープンソースのGitサーバ、GitBucket 4.6をリリースしました。

https://github.com/takezoe/gitbucket/releases/tag/4.6

リポジトリのフォークを禁止するオプション

リポジトリの設定でフォークを禁止できるようになりました。

f:id:takezoe:20161023025446p:plain

WikiページにHistoryボタンを追加

これまでHistoryボタンはWikiページの編集画面にしか表示されていませんでしたが、参照画面にも表示されるようになりました。

f:id:takezoe:20161023025551p:plain

Gitリポジトリのリダイレクト

JenkinsなどGitHub前提の外部ツールとの連携をやりやすくするためにGitHub風URLでのGitリポジトリへのHTTPアクセスをリダイレクトするようになりました。

http://localhost:8080/user1/gitbucket.git

上記のURLは以下にリダイレクトされます。

http://localhost:8080/git/user1/gitbucket.git

Get-Content APIの改善

Get-Content APIはこれまでディレクトリしかサポートされていませんでしたが、ファイルにも対応しました。

  • API呼び出し:
$ curl http://localhost:8080/api/v3/repos/user1/gitbucket/contents/project/build.properties
  • レスポンス
{
  "type":"file",
  "name":"build.properties",
  "content":"c2J0LnZlcnNpb249MC4xMy4xMgo=",
  "encoding":"base64"
}

また、カスタムメディアタイプもサポートしています。リクエスト時にAcceptヘッダを指定することでレスポンスのデータ型を選択することができます。Acceptヘッダが指定されていない場合はBase64エンコードされたコンテンツを含むJSONを返します。

  • 生データを要求する場合:
$ curl http://localhost:8080/api/v3/repos/user1/gitbucket/contents/project/build.properties \
-H "Accept: application/vnd.github.v3.raw"
  • HTMLを要求する場合:
$ curl http://localhost:8080/api/v3/repos/user1/gitbucket/contents/project/build.properties \
-H "Accept: application/vnd.github.v3.html"

グループのメンバー一覧で管理者を表示

グループのMembersタブのメンバー一覧で、誰がグループの管理者かわかるよう管理者にはマークを表示するようにしました。

f:id:takezoe:20161029151447p:plain

この他にも様々な改善やバグフィックスを行っています。詳細についてはIssueの一覧をご覧ください。

ScalaでタイプセーフにCSSを記述できるScalaCSSを使ってみる

Scala Warriorではユーザが入力したコードを実行する目的でScala.jsを使っているのですが、せっかくScala.jsを使っているのでフロントエンドもできるだけScalaで書いてみようと思い、ScalatagsやScalaCSSなどを試しています。今日はScalaCSSについて紹介してみたいと思います。サンプルコードはScalaCSSのドキュメントから持ってきています。

github.com

ScalaCSSはScalaのコードからCSSを生成するためのライブラリで、CSSをタイプセーフに記述・参照できたり、Scalaコードで動的にスタイルを定義できたりといった便利な機能があります。Scala.jsにも対応しており、大きく分けでスタンドアロンモードとインラインモードの2通りの使い方があります。

スタンドアロンモード

スタンドアロンモードはこんな感じで記述します。

import scalacss.Defaults._

object MyStyles extends StyleSheet.Standalone {
  import dsl._

  "div.std" - (
    margin(12 px, auto),
    textAlign.left,
    cursor.pointer,

    &.hover -
      cursor.zoomIn,

    media.not.handheld.landscape.maxWidth(640 px) -
      width(400 px),

    &("span") -
      color.red
  )

  "h1".firstChild -
    fontWeight.bold

  for (i <- 0 to 3)
    s".indent-$i" -
      paddingLeft(i * 2.ex)
}

通常の外部CSSファイルの代わりに使う感じですね。Scalaコードを記述できるので繰り返しや条件分岐などを使って動的にスタイルを定義することも可能です。定義したCSSは以下のようにして出力することができます。

println(MyStyles.render)

インラインモード

これに対してインラインモードの場合は以下のような感じで定義します。

import scalacss.Defaults._

object MyStyles extends StyleSheet.Inline {
  import dsl._

  val common = mixin(
    backgroundColor.green
  )

  val outer = style(
    common, // Applying our mixin
    margin(12 px, auto),
    textAlign.left,
    cursor.pointer,

    &.hover(
      cursor.zoomIn
    ),

    media.not.handheld.landscape.maxWidth(640 px)(
      width(400 px)
    )
  )

  /** Style requiring an Int when applied. */
  val indent =
    styleF.int(0 to 3)(i => styleS(
      paddingLeft(i * 2.ex)
    ))

  /** Style hooking into Bootstrap. */
  val button = style(
    addClassNames("btn", "btn-default")
  )
}

定義したCSSスタンドアロンモードと同じく以下のようにして出力できます。

println(MyStyles.render)

また、以下のようにしてHTMLタグのclass属性に指定する値を取得することができます。これを使ってclass属性を出力しておくことでクラス名の記述ミスを防いだり、リファクタリング時などに使用箇所を容易に特定することができます。

MyStyles.outer.htmlClass     // Returns "MyStyles-outer"
MyStyles.indent(1).htmlClass // Returns "MyStyles-indent-1"
MyStyles.indent(2).htmlClass // Returns "MyStyles-indent-2"
MyStyles.button.htmlClass    // Returns "btn btn-default"

ScalaCSSの便利機能

Scalaコードならではの便利機能がいろいろあります。たとえばSCSSのmixinのようなスタイルの使い回しは以下のように記述できます。

val button = style(margin(8 px, auto), ...)
val userTitle = style(marginLeft(4 ex), ...)

val userButton = style(button, userTitle, ...)

合成した場合にスタイルの定義が重複している場合は以下のように警告を出力することができるようです。

[CSS WARNING] .MyStyles-navbar -- {margin-left: 6px} conflicts with {margin: 12px}
[CSS WARNING] .MyStyles-button -- {cursor: zoom-in} conflicts with {cursor: pointer}

また、他のCSSフレームワークと組み合わせて使用する場合などは以下のようにしてScalaCSSのインラインモードで定義するスタイルにclass属性の値を追加しておくことができます。こうしておくとhtmlClassで出力する値に追加したクラス名も含まれるようになります。

val button = style(
  addClassNames("btn", "btn-default"), // Bootstrap classes
  textAlign.center                     // Optional customisation
)

個人的にはsbt-webで定義したスタイルを外部CSSファイルに出力してくれるようなsbtプラグインがあるといいかもと思いました。

まとめ

ScalaCSSはScalaCSSを記述するDSLとしてはそれなりに使いやすいライブラリです。

が、フロントエンドのツールチェーンに組み込めなかったり、そもそもフロントエンジニアがScalaを書くのか?といった問題があり、現実的には一般的な開発体制ではなかなか使いにくいのではないかと思います。Scala.jsにしても(そもそもScala.js自体使うのかという問題はさておき)、フロントエンドの開発に使うというよりは、サーバサイドのエンジニアがフロントエンジニアにインターフェースを提供するために使うのがベストプラクティスと言われるようになってきています。

そういうことも考えるとScalaCSSに限らずScalaのフロントエンドソリューションは(GitBucketやScala Warriorのように)少人数のScalaプログラマでサーバサイドからフロントエンドまで開発している特殊なプロジェクト以外では使うモチベーションを見出すのが難しいかもしれません。