情報は力ではない

UE4 とか Blender とか。

JavaScriptの論理演算子の評価値

最近、サイ本を読んでいます。 その中で少し驚いたものを一つ紹介したいと思います。

以下の論理演算子が何を返すかという話をします。

var o = { a: 0 };

var b1 = o && o.a;
var b2 = undefined && o;
var b3 = o || "";
var b4 = null || undefined

値の論理値への変換

JavaScriptの値は、すべて論理値に変換可能できます。 次の値は全てfalseに変換されます。

  • undefined
  • null
  • 0
  • -0
  • NaN
  • ""

上記以外の値は、すべてtrueに変換されるので、次の式はtrueに変換されることになります。

{ a: 0 }

&&演算子と||演算子

&&演算子は次のような処理を行う。 1. 左の被演算子が「falseに評価されるもの」であれば、それを返す。 2. 左の被演算子が「trueに評価されるもの」であれば、右の被演算子を返す。

||演算子は次のような処理を行う。 1. 左の被演算子が「trueに評価されるもの」であれば、それを返す。 2. 左の被演算子が「falseに評価されるもの」であれば、右の被演算子を返す。

ですので、この記事の冒頭で示した論理演算子の評価値は次のようになります。

var o = { a: 0 };
var b1 = o && o.a; // 0
var b2 = undefined && o; // undefined
var b3 = o || ""; // { a: 0 }
var b4 = undefined || null; // null

面白いと思うのは、trueやfalseを返すということではないということです。 これを用いると引数がnullやundefinedのときのデフォルト値を設定することができます。

function foo(x) {
  // xがfalseと評価されるものであれば、xは{a: 0}となる
  var x = x || { a: 0 };

  // ...
}

ただ、このxにtrueかfalseが入っているようにも見えるので、初心者はハマるかもなぁという感想です。

ほぼすべてサイ本の内容そのままという感じですが、自分でまとめると ちゃんとわかっているかの確認になってよいなという感じです。 今後もまたサイ本を読んで気になった箇所の記事を書きたいと思います。

www.amazon.co.jp

Vimの起動時間を計測する。

概要

Vimの起動時間を計測するには次のようにする。
{fname}にその結果が書き込まれる。

vim --startuptime {fname}

内容

Vimの起動時間を計測するには、--startuptimeオプションをつけてVimを起動する。このオプションには引数としてファイル名が必要。
helpによると、startuptime付きでVimコンパイルした時のみ有効だそうです。

例えば、次のように起動すると、hoge.txtに起動時の経過時間のメッセージが記述される。

vim --startuptime hoge.txt

hoge.txtの内容は次のような感じになってるはず。

times in msec
 clock   self+sourced   self:  sourced script
 clock   elapsed:              other lines

000.007  000.007: --- VIM STARTING ---
000.082  000.075: Allocated generic buffers
000.500  000.418: locale set
000.507  000.007: clipboard setup
000.517  000.010: window checked
002.179  001.662: inits 1
(略)
156.321  000.116: BufEnter autocommands
156.324  000.003: editing files in windows
156.892  000.568: VimEnter autocommands
156.899  000.007: before starting main loop
157.412  000.513: first screen update
157.414  000.002: --- VIM STARTED ---

左の列が起動開始からの時間(msec)で、次の列が、それぞれの処理にかかった時間(msec)になる。
これを使うことで、プラグインの読み込み時にかかる時間も確認することができる。

ヘルプ

:help --startuptime

Mockitoの@InjectMocksは何を見てInjectするのか

InjectMocks (Mockito 2.0.36-beta API)に書いてます。
思った挙動と異なっていたので、自分のためにメモ。

次のようなSampleクラスがあったとする。

public class Sample {
    private final Hoge hoge;
    private final Fuga fuga;

    private HogeHoge hogehoge;

    public Sample(Hoge hoge, Fuga fuga) {
        this.hoge = hoge;
        this.fuga = fuga;
    }

    public Hoge getHoge() {
        return hoge;
    }

    public Fuga getFuga() {
        return fuga;
    }

    public HogeHoge getHogeHoge() {
        return hogehoge;
    }
}

このクラスに対するテストを次のように書いて実行すると、コメントの部分でAssertionErrorになる。

public class SampleTest {
    @Mock
    Hoge hoge;

    @Mock
    Fuga fuga;

    @Mock
    HogeHoge hogehoge;

    @InjectMocks
    Sample sample;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void test() {
        assertEquals(hoge, sample.getHoge());
        assertEquals(fuga, sample.getFuga());
        assertEquals(hogehoge, sample.getHogeHoge());  // ここでAssertionError
    }
}

自分は最初、MockitoAnnotations.initMocks()を呼び出すことで@Mockを指定したすべてのクラスがSampleクラスにInjectされると思ってたが、違うようだった。
そこで、この記事の最初に掲載したドキュメントを読むとConstrucor injection, Setter injection, Field injectionのいずれか"のみ"でInjectされることがわかった。
Sampleクラスの場合、Constructor injectionが行われていて、HogeクラスとFugaクラスがInjectされる。Constructor Injectionが成功したので、HogeHogeクラスはInjectionされることがないようだ。

ちゃんとドキュメントは読むべきなのだなあと改めて思った出来事だった。

ハル研究所プログラミングコンテスト2015

一昨年のハル研プロコン2014に引き続き、去年もハル研プロコンに参加しました。
ハル研究所 プログラミングコンテスト2015 | TOP

今年の問題は宅配便でした。
問題の雰囲気は、車両配送問題(Vehicle Routing Problem, VRP)っぽい感じです。

開催されてからすぐに最適解らしいスコアが上位に現れ、そのスコアの人が上位に連なり、最終的には上位10人が同じスコアになり、1秒未満の戦いが上位で繰り広げられていました。
自分はそんな上には行けませんでした。うーん、悔しい。

自分は普段からコンテストに出ているような人ではないので、いろいろな解法を試してみようと思いながらちょくちょく回答を書いていました。

とかを実装してました。
動的計画法ではなぜかスコアが伸びなかったので(おそらく実装力のなさが原因)、最終的にはビームサーチに頼ってました。
評価関数どうするかがわからなくて結局スコア伸びなかったのですが。

今年度で学生が終わるのでハル研プロコンに出れるのが今回で最後。
今回のプロコンは最適解を出せて初めてスタートラインに立つようなものなので、最後のプロコンでスタートラインに立てなかったのは悔しさが残ります。
でもハル研プロコンに参加して、自分の雑魚さがよくわかったので良かったかなと思います。何より楽しかった。
ハル研プロコン実行委員会の皆さま、楽しいひと時をありがとうございました。


最終的な結果は1月29日に出るようです。

Material Design GuideのListsを読んだ。

そろそろMaterial Designについても知りたいなぁと思ってきたので、Material Designのサイトの気になるところから読んでいる。
今日はListsとLists: Controlを読んだ。
Lists - Components - Google design guidelines
Lists: Controls - Components - Google design guidelines
そこで初めて知ったり、覚えておこうと思ったものを少しメモしておく。
引用の英文を訳しているけど、雰囲気で訳しているので英文と日本語の文は同じ意味じゃないと思う。

リストの要素のテキストの行数が3行より多い場合はCardを使う

If more than three lines of text need to be shown in list tiles, use cards instead.

リストの要素の一番目立つコンテンツが画像ならグリッドリストを使う

If the primary distinguishing content consists of images, use a grid list.

リストの要素の中で最も目立つものは左に置き、最も目立つテキストは最初の行に書く

Bias the most distinguishing content in a tile towards the left of the tile. In tiles with mutli-line content, place the most distinguishing content in the first line.

とりあえず以上。
googleさんのドキュメント量はすごいなぁ。

VimConf 2015に行ってきた。

VimConf 2015に行ってきました。

発表者の方々のスライドへのリンクは次のURLにあります。
http://vimconf.vim-jp.org/2015/#agenda

セッションについては他の方々が紹介していると思うのでそちらにお任せしたいと思います。
申し訳ありません。*1

懇親会

懇親会が始まる前にピザを運ぶのを手伝わさせていただきました。
たくさんのピザを運ぶお手伝いを今までしたことがないので貴重な体験となりました。

このような懇親会に参加するのは初めてなので、どのようにたち振る舞えば良いのかわからなかったのですが
数人の方に話しかけていただきました。本当にありがとうございます。
derisさんに話しかけていただいたのですが、その時すかさずduzzle.vimが好きだということを伝えました。
懇親会ではほとんどVimについて話していないことに気づきました。
それでも非常に楽しいひと時となりました。

終わりに

今回まとめ役をしていただいた@dictavさん、運営の皆さん、発表者の皆さん、会場を貸していただいたmixiさん、ありがとうございました。
是非来年も参加したいと思います!

これで自分のVimConf 2015も終わりです。

*1:自分の不注意でセッションの感想を消してしまいました。

Android Data Bindingを使ってみた。

最近ちょこちょことtechbooster.fmを聞いているのですが、第11回でDataBindingの話をしていて、その存在を知ったのでちょっと使ってみた。
詳しい使い方についてはData Binding Guide | Android Developersに詳しく書いている(はず)です。まだ読んでないです。
以下で出てくるコードはこのサイトに載っているコードです。

準備

appモジュールのbuild.gradleにdataBinding要素を追加する

android {
  ...
  dataBinding {
    enabled = true
  }
}

これだけです。

使い方

DataBindingをするにはlayoutファイルを次のように記述するとcom.example.UserクラスのfirstNameフィールドがTextViewにバインド?される。

<!-- res/layout/main_activity.xml -->
<layout xmlns:android="http://schemas.android.com/apk/res/android">
  <data>
    <variable name="user" type="com.example.User"/>
  </data>
  <LinearLayout
    ...>
    <TextView ...
      android:text="@{user.firstName}"/>
  </LinearLayout>
</layout>

重要な点は4つ。

  1. ルートタグとして<layout>を使うこと
  2. <layout>タグの直後に<data>要素を記述すること
  3. <data>要素の中に<variable>要素を指定し、バインドしたいクラスを指定すること
  4. バインドしたクラスのフィールドを指定するには@{}構文を使用すること

あとは次のようなコードを記述すればDataBindingが行われる。

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
  User user = new User("Test", "User");
  binding.setUser(user);
}

ここで出てくるMainActivityBindingクラスはDataBindingライブラリによってコンパイル時に作成されるクラスです。
先ほど、main_activity.xmlを書いたのでMainActivityBindingクラスが生成されています。
このBindingクラスの名前はlayoutファイル名をキャメルケースしたものの末尾にBindingという文字列をくっつけた名前になります。
例えばlayoutファイルの名前がitem_view.xmlであればItemViewBindingクラスが生成されることになります。

感想

すごく簡単にしか使ってないけど、結構便利そう。
下の動画でも言っているけど、RecyclerViewを使うときのAdapterやHolderの記述が簡潔に書ける。

www.youtube.com
他のDataBindingライブラリとしてButterKnifeの存在は知っていたけど、なんとなく使うのを面倒に感じていて今まで使っていなかった。
今回のtechbooster.fmがDataBindingを使うきっかけになりました。非常に感謝です。
これからも少しずつDataBindingを使っていこうと思う。