Ruby で xlsx を編集する

Ruby で既存のエクセルファイルを編集したかったので試してみた。
Ruby でエクセルファイルを扱う手段(gem)はいくつかあるが今回は、

  • .xlsx ファイルの読み込み
  • .xlsx ファイルの書き込み
  • セルの結合

を行いたかったので RubyXL を使うことにした。

余談

最初は spreadsheet を使おうと思って試してみたが、これは .xls.xlsx ではない)しか読み書きが出来ないのでボツに。
次に .xlsx が読み込める roo を試してみたが、これも .xlsx の読み込みはできるけど、書き込みが出来ないのでやっぱりボツに。
また axlsx も使い勝手とかはよさそうだったが、これはファイルの読み込み自体が行えずに(ry。
このように Rubyge でエクセルを扱う gem はいくつか存在するが、全体的にかゆいところに手が届かない。
と、いうような問題を解決するためにエクセルを扱う gem の機能を共有した rrxcell というものが存在しており、これであれば .xlsx の読み書きを行うことが出来る。
しかし、残念ながら rrxcell では『セルの結合』を行うことが出来なかったのであえなく撃沈した。
そういうわけで、今回は全ての条件を満たす RubyXL を使うことにした。

インストール

$ gem install rubyXL

使い方

require "rubyXL"

src  = "test.xlsx"
dest = "output.xlsx"

# エクセルファイルの読み込み
book = RubyXL::Parser.parse(src)

# シートを取得
sheet = book[0]


# シートのセルを結合する

# 行3, 列 0 のセル位置
cell1 = [3, 0]
# 行3, 列 1 のセル位置
cell2 = [3, 1]

# cell1 と cell2 を結合する
sheet.merge_cells *cell1, *cell2
# 以下と等価
# sheet.merge_cells 3, 0, 3, 1

# ファイルの保存
book.write(dest)

所感

とりあえず、やりたかったことは出来たので満足。

参照

Electron で jQuery 使う場合の注意点

Electron で UIkit を使っていたらハマったので覚書。
問題点としては、

  • Electron で jQuery を使おうとするとエラーが出た
  • 上記の問題を解決した結果、gulp のライブリロードが動作しなくなった

という2つの不具合が発生した。
先に書いておくと手元では下記の対応で問題なく動作したが JavaScript にそこまで詳しくはないのでこれが最善かどうかは不明です。

動作環境

  • Electron v1.7.5
  • jQuery v3.2.1
  • UIkit v3.0.0-beta.30

Electron で UIkit3(jQuery) を使う場合の問題点

Electron で UIkit3 とそれに依存している jQuery を使おうとすると

Uncaught TypeError: Cannot use 'in' operator to search for 'default' in undefined

というようなエラーがでる。
これは Electron と jQuery が競合してるからぽいらしい?(このあたりはよくわかってない…。
とりあえず、間接的でも Electron で jQuery を使う場合は以下のような設定を追加することで対処することが出来る。

BrowserWindow の生成オプションを追加する

BrowserWindow を作る際に nodeIntegrationfalse に設定することで解決することが出来る。

const {BrowserWindow} = require('electron')
let win = new BrowserWindow({
  webPreferences: {
    // この設定を追加する
    nodeIntegration: false
  }
})
win.show()

HTML 側で jQuery を読み込む前に対処する

HTML 側で jQuery を読み込む前に以下のようなコードを挿入することで解決する事が出来る。

<head>
<script>
window.nodeRequire = require;
delete window.require;
delete window.exports;
delete window.module;
</script>
<script type="text/javascript" src="jquery.js"></script>
</head>

上記のどちらか一方で解決することができるので対処しやすい方を選択するとよいだろう。

gulp を使ったライブリロードを動作させる

上記の設定で Electron と jQuery が競合する問題は解決した。
しかし、今度は gulp を使ったライブリロードが動作しなくなってしまったので対処法を書いておく。
gulp を使ったライブリロードを行う場合、HTML 側で

<script>
require('electron-connect').client.create()
</script>

というようなスクリプトを追加する必要がある。
しかし、先ほど対処した方法では require(や exportmodule)が削除されてしまい、上記のスクリプトがエラーになってしまう。

スクリプトの定義順を変える

本来は import などを使うべきなのだろうが、手元だと上手く動作しなかったので定義順を変えることで対処した。

<head>
<script>
require('electron-connect').client.create()
window.nodeRequire = require;
delete window.require;
delete window.exports;
delete window.module;
</script>
<script type="text/javascript" src="jquery.js"></script>
</head>

これで動作するはずである。
ちなみに nodeIntegration を追加する方法だと対処できないので HTML 側で対処を行う必要がある。

参考

今更聞けない! Ruby の継承と mixin の概念を継承リストから学ぶ

Ruby を学ぶ上で継承と mixin の概念を理解することはとても重要である。
しかし、このあたりの仕組みを学ぼうとすると、includeprepend、特異クラスや特異メソッドなどという様々な機能を理解する必要がありとても複雑である。
そこで本記事は『継承リスト』という観点から継承を mixin を学んでみたいと思う。
また、この記事は Ruby 2.4 時点での仕様になる。

継承と mixin

まず、はじめに Ruby での継承と mixin の仕方をみてみよう。
Ruby では継承で既存のクラスを、mixin でモジュールをそれぞれクラスに取り込むことが出来る

継承

class Super
    def super_method
        :super_method
    end
end

# Super クラスの機能(メソッド)を Sub クラスで継承(取り込む)する
class Sub < Super
end

# Super クラスのメソッドが利用できる
p Sub.new.super_method
# => :super_method

mixin

module Mod
    def mod_method
        :mod_method
    end
end

class X
    # Mod モジュールの機能(メソッド)を X クラスで取り込む
    include Mod
end

# Mod モジュールのメソッドが利用できる
p X.new.mod_method
# => :mod_method

他にも #extend#prepend といったメソッドでモジュールを mixin することが出来る。
継承も mixin も『外部の機能をクラスに取り込む』という意味では共通だが、

  • 1つのクラスしか継承する事が出来ない(継承してるクラスを継承するのは可)
  • 複数のモジュールを mixin することが出来る

という点で少し異なる。
また、継承と mixin は同時に利用することも可能である。

class Super
    def super_method
        :super_method
    end
end

module Mod
    def mod_method
        :mod_method
    end
end

class X < Super
    include Mod
end

x = X.new
p x.super_method
# => :super_method

p x.mod_method
# => :mod_method

Module#ancestors

ここまで読んで『継承と mixin が複数あってややこしい…』と思うかもしれない。
そこでまずは継承関係を『継承リスト』という形で視覚化してみてみよう。
継承リストは Module#ancestors メソッドで取得する事が出来る。
Module#ancestors はクラスオブジェクトをレシーバとして呼び出すことができ『クラス、モジュールのスーパークラスとインクルードしているモジュール を優先順位順に配列に格納して返す』というメソッドである。

see:https://docs.ruby-lang.org/ja/latest/method/Module/i/ancestors.html

説明を聞いてもよくわからないと思うので実際に試してみよう。
例えば、Integer であれば

p Integer.ancestors
# => [Integer, Numeric, Comparable, Object, Kernel, BasicObject]

となり、String であれば

p String.ancestors
# => [String, Comparable, Object, Kernel, BasicObject]

となる。
これは単純に

BasicObject
↑
Kernel
↑
Object
↑
Comparable
↑
Numeric
↑
Integer

というような『継承関係にある』と考えれば理解しやすいだろう(厳密に『継承』と言ってしまうと正しくはないが…。
また継承リストには『レシーバのクラス』も含まれている。
ちなみにユーザが定義したクラスは暗黙的に Object を継承することになる。

class X
end

p X.ancestors
# => [X, Object, Kernel, BasicObject]

更に継承を行った場合は Object と定義したクラスの間に継承したクラスが挿入される。

class Super
end

class Sub < Super
end

p Sub.ancestors
# => [Sub, Super, Object, Kernel, BasicObject]

このように Module#ancestors を使うことでそのクラスの『継承リスト』を確認する事が出来る。

メソッドを呼び出す優先順位

ここで少し継承と mixin から離れて『メソッドの探査』について考えてみよう。
と、言っても実はそんなに難しくない。メソッドの探査は
『継承リストの先頭から走査して最初に定義されているクラスのメソッドを実行する』
というような形になる。

class Super
    def mami
        "mami"
    end

    def homu
        "homu"
    end
end

class Sub < Super
    # Super クラスのメソッドを上書きする
    def homu
        "homuhomu"
    end
end

# Super よりも Sub のほうが優先順位が高い
p Sub.ancestors
# => [Sub, Super, Object, Kernel, BasicObject]

sub = Sub.new

# Sub では定義されていないので次の Super のメソッドが呼び出される
p sub.mami
# => "mami"

# Sub で定義されているので Sub のメソッドが呼び出される
p sub.homu
# => "homuhomu"

# Sub でも Super でも定義されていないので、Kernel で定義されているメソッドを呼び出す
p sub.class
# => Sub

ここで重要なのが『継承リストがそのままメソッド探査の優先順位になる』という点である。
逆にいえば『メソッド探査は継承リストに依存してる』ともいえる。
このあたりは重要なので覚えておくとよい。
余談だが、Method#owner でメソッドが定義されているクラス/モジュールを確認する事が出来る。

sub = Sub.new
p sub.method(:mami).owner
# => Super

p sub.method(:homu).owner
# => Sub

p sub.method(:class).owner
# => Kernel

mixin したクラスの #acestors をみてみる

これまでの流れで、

  • 継承リストは Module#ancestors で取得する事が出来る
  • 継承リストには自身も含まれている
  • メソッド探査の優先順位は継承リストに依存する
  • 継承を行うと継承したクラスが継承リストに挿入される

と、いうことがわかったと思う。
では、#include でモジュールを mixin をするとどうなるか。
実際に試してみよう。

module Mod
end

class X
    include Mod
end

# Mod がいる!!
p X.ancestors
# => [X, Mod, Object, Kernel, BasicObject]

あれ、 mixin しても継承リストに追加されてる!?
そう、mixin も実は単に継承リストに追加されるだけなのだ。
ちなみに先程から継承リストに存在している Kernel も実はクラスではなくて『Object に mixin されているモジュール』なのである。

p Kernel.class
# => Module

継承と mixin を両方使ってみると

では、継承と mixin の両方を行うとどうなるのか試してみよう。

class Super
end

module Mod
end

class X < Super
    include Mod
end

p X.ancestors
# => [X, Mod, Super, Object, Kernel, BasicObject]

上のコードの実行結果を見てもらうと Mod モジュールとと Super クラスが継承リストに追加されていることがわかる。
また、継承リストから見てわかる通り、継承と mixin を行った場合は mixin のほうが前に挿入されていることがわかる。
これにより『mixin を行ったモジュールのメソッドを優先して』呼び出されることになる。

class Super
    def homu
        "Super#homu"
    end
end

module Mod
    def homu
        "Mod#homu"
    end
end

class X < Super
    include Mod
end

p X.new.homu
# = > "Mod#homu"

ちなみに複数のモジュールを mixin した場合は『あとから mixin したモジュール』の優先順位が高くなる。

module Mod1
end

module Mod2
end

class X
    include Mod1
    include Mod2
end

p X.ancestors
# = > [X, Mod2, Mod1, Object, Kernel, BasicObject]

このように継承も mixin も『継承リストに挿入されているだけ』に過ぎないのである。

prepend する

ところで Ruby 2.0 で Module#prepend というメソッドが追加された。
これは #include と同様にモジュールを mixin する機能であるが、『優先順位が mixin されたクラスよりも高い』という特性がある。

module Mod
    def homu
        "Mod#homu > #{super()}"
    end
end

class X
    prepend Mod

    def homu
        "X#homu"
    end
end

# X#homu ではなくて Mod#homu が呼ばれる
p X.new.homu
# "Mod#homu > X#homu"

このように #prepend したモジュールのメソッドが自身のクラスのメソッドよりも優先して呼ばれる。
では、これも継承リストを見てみよう。

module Include
end

module Prepend
end

class X
    include Include
    prepend Prepend
end

p X.ancestors
# => [Prepend, X, Include, Object, Kernel, BasicObject]

#include したモジュールと比較すると #prepend したモジュールが『自身のクラスよりも前に』継承リストに挿入されている事がわかる。
このようにして継承リストを確認することで『自身よりも #prepend したモジュールが優先して呼ばれる理由』も納得すると思う。
こうしてみると難しそうな #prepend も単純に『継承リストに挿入する位置が違うだけ』なのがわかると思う。
まとめると

  • #include はクラスよりも前に継承リストに挿入される
  • #prepend はクラスよりも後に継承リストに挿入される

という形になる。

singleton_class.ancestors をみている

ここまで来たら特異メソッドについても考えみよう。
Ruby ではクラスだけではなくて『インスタンスに対しても』メソッドを定義することができる。
また、そのメソッドはクラスで定義されているメソッドよりも優先して呼ばれる。

class X
    def homu
        "X#homu"
    end
end

x = X.new

def x.homu
    "x.homu"
end

p x.homu
# => "x.homu"

このように『インスタンスに対して定義されるメソッド』のことを『特異メソッド』と呼ぶ。
また、特異メソッドは『特異クラス』という特殊なクラスに定義される。
この特異クラスは『各オブジェクトが必ず1つ持っている』クラスになる。

class X
end

# X クラスの特異クラス
p X.singleton_class
# => #<Class:X>

x = X.new

# x インスタンスの特異クラス
p x.singleton_class
# => #<Class:#<X:0x00000001275e10>>

ちょっと複雑になってきたので特異メソッドと特異クラスはこのあたりにしてメソッド探査の話をしよう。
メソッド探査が継承リストに依存しているのはこれまで話したとおりである。
と、いうことで特異クラスの継承リストを確認してみよう。

class X
end

x = X.new

p x.singleton_class
# => #<Class:#<X:0x00000001828790>>
p x.singleton_class.ancestors
# => [#<Class:#<X:0x00000001828790>>, X, Object, Kernel, BasicObject]

上のコードを見てもらうと『特異クラスが自身の継承リストに追加されている』事がわかる。
なのでメソッド探査に依存する継承リストというのは正確にいえば『自身の特異クラスの継承リスト』ということになる。
これにより『クラスで定義されたメソッド』よりも『特異クラスで定義されたメソッド=特異メソッド』が優先されるのである。

#extend してみる

最後に #extend について説明しておく。
これも #include#prepend と同様にモジュールを mixin する機能であるが『特異クラスに mixin する』という点が他のメソッドと異なる。

module Mod
    def homu
        "Mod#homu"
    end
end

class X
end

x = X.new

# Mod のメソッドが x オブジェクトに定義される
x.extend Mod

p x.homu
# => "Mod#homu"

# 特異クラスの継承リストに extend したモジュールが追加されている
p x.singleton_class.ancestors
# => [#<Class:#<X:0x000000017a51b0>>, Mod, X, Object, Kernel, BasicObject]

このように #extend は『特異クラスの継承リスト』に追加される。
逆にいえば

x.extend Mod

x.singleton_class.include Mod

と同等ともいえるだろう。

おまけ:特異メソッドよりも優先するメソッドを定義する

おまけ。
特異クラスに対して #prepend することで特異メソッドよりも優先されるメソッドを定義することが出来る。

module Mod
    def homu
        "Mod#homu"
    end
end

class X
end

x = X.new
def x.homu
    "x.homu"
end
p x.homu
# => "x.homu"

p x.singleton_class.prepend Mod
p x.homu
# => "Mod#homu"

# 特異クラスよりも前に挿入されている事がわかる
p x.singleton_class.ancestors
# => [Mod, #<Class:#<X:0x00000001094dd0>>, X, Object, Kernel, BasicObject]

滅多にないと思うが一番優先したいメソッドを定義したい場合はこういう手段が考えられる。

まとめ

  • メソッド呼び出しの優先順位は継承リストに依存する
  • 継承リストは Module#ancestors で確認できる
  • 継承も mixin も継承リストにクラス/モジュールを挿入する機能に過ぎない
  • #include はクラスよりも前に継承リストに挿入される
  • #prepend はクラスよりも後に継承リストに挿入される
  • 特異メソッドは特異クラスに定義される
  • 特異クラスは継承リストの一番手間に挿入されるのでメソッド探査の優先順位が一番高い
  • メソッドの探査はレシーバの『特異クラスの』継承リストに依存する
  • #extend は特異クラスの継承リストに挿入される

このように継承や mixin は継承リストが中心となって機能していることがみてとれる。
メソッド探査のまとめは以下のようになる。

スーパークラス
↑
include したモジュール
↑
自身のクラス
↑
prepend したモジュール
↑
インスタンスが extend したモジュール
↑
インスタンスの特異クラス(特異メソッド)

Ruby では外部で定義されているメソッドを取り込む機能として継承や includeprepend など手段が分散されており複雑なので理解するのが難しい。
しかし、継承リスト(#ancestors)を参照することでなんとなく仕組みがわかったのではないだろうか。
もし、意図しないメソッドが呼び出される問題が発生した場合は継承リストを確認してみるとよいだろう。
ちなみに特異クラスでも #include#prepend を行うことができるので、継承リストがどうなるのか気になるのであれば手元で試してみるとよいだろう。

参照

LLVM 5.0.0 がリリース

LLVM 5.0.0 がリリースされました。
こちらからダウンロードすることが出来ます。
リリースノートは以下を参照してください。

std::for_each の戻り値

std::for_each の戻り値って void だと思っていたんですが、どうやら第三引数が返ってくるらしい。

#include <vector>
#include <iostream>

int
main(){
    std::vector<int> v{1, 2, 3, 4, 5};
    std::for_each(v.begin(), v.end(), [](auto n){
        std::cout << n << std::endl;
    })(42);

    struct adder{
        int value = 0;
        void operator()(int n){ value += n; }
    };
    auto sum = std::for_each(v.begin(), v.end(), adder{});
    std::cout << sum.value << std::endl;

    return 0;
}
/* output:
1
2
3
4
5
42
15
*/

一番最後に処理を追加したい場合とか、副作用がある関数オブジェクトを指定している場合に便利そう。

[参照]

Linux 上で Unity を使って遊んでみた

Unity と言えば動作環境が Windows/Mac で『興味あるけど Ubuntu で使えないしなー』と思ってたんですが、一応 Linux 版も開発されているらしく、それが問題なく使えると聞いたので試してみました。

ダウンロード/インストール

Unity は以下のページからダウンロードすることが出来ます。

一番下にあるのが最新版になのでダウンロードするときは注意してください(わたしは最初に一番上にあるパッケージをインストールして動作しなくて死にました。
記事を書いた時点では 2017.2.0b6 が最新版になります。
こちらから .deb のパッケージをダウンロードすることが出来ます。
パッケージファイルは 2.8GB と結構大きいので注意してください。
インストール自体は特に問題なく出来ると思います。
また、Unity を使用する際には Unity のサイトでアカウント登録しておく必要があるので、ダウンロードしてある間にでも登録しておくとよいと思います。
その他必要なツールとかは Windows/Mac とかと一緒…だと思う…。
とりあえず、以下に書いてあるチュートリアルは問題なく動作しました。

チュートリアル

公式のチュートリアルは動画ベースでわかりづらかったのでこちらを参考にしながら試してみました。
かなり丁寧に書かれているのでわかりやすく Unity について学ぶことが出来ました。

所感

と、いうことでチュートリアルをやっただけですがなんとなーく Unity の概念みたいなのはわかったような気がしました。
率直な意見としてはイメージ通り…っていうか当然ですが
『プログラミングでゲームをつくってる』
というよりは
『グラフィックツールをいじってる』
って感じが強かったですね。
『パーツを組み合わせてゲームをつくってる』っていう意味では面白かったんですが、ツールとしての使い方や構成なんかはプログラミングとはまた違った学習になるので大変そうです。
特にオブジェクト間のひも付けなどの仕組みは表面上に出てこないので概念を学ぶのは難しそうですね…。
以下、ざっくりとした感想。

  • オブジェクト間のひも付けが簡単
  • 思ったよりも直感的に操作することが出来た
  • C# が思ったよりも苦痛ではない
  • (レイアウトの問題もあるだろうけど)ツール自体のウィンドウが横に長くなるのがつらい
  • 少しでも意図しない動作が発生しただけで何をすればいいのかがわからなくなる
  • Unity 上ではエラーが出力されているけど何故か動作する
  • 基本的にマウス操作ばっかりなのでつらい
  • 3Dオブジェクトの配置とか Transfrom とか数値をいじってるのがつらい
  • コードを書きたくなってくる
  • でもやっぱり動作したら楽しい

と、いう感じでさくっと…というわけには行きませんが手軽に 3D ゲームを作りたい場合はかなり便利な装置って感じですね。
『ゲームをつくる』っていう目的に特化するのであればプログラミングを覚えるよりかはこういうツールで作るほうが効率的だと思いました。
まあ個人的には『ひたすら汎用的なコンポーネントをつくりたい』っていう欲求が高まってきましたが。
せっかくなのでもう少しいろいろとゲーム作って遊んでみたいなー。
ところで Web 系ってフレームワークは多いですが、こういう『統合開発環境エンジン』みたいな方向で進化したりしないんですかね。

Ruby でメソッドの呼び出し元の情報を取得する

例えば、次のコードのように『A.hoge の呼び出し元の情報』を取得したいことがあります。

module A
    def self.hoge
        # 呼び出し元である X オブジェクトを取得したい
    end
end

class X
    A.hoge
end

標準の範囲だとできなさそうだったんですが、binding_of_caller という gem を使えば実現出来るみたいです。

使い方

$ gem install binding_of_caller

使い方

require "binding_of_caller"

module A
    def self.hoge
        # 呼び出し元のコンテキストで式を評価出来る
        p binding.of_caller(1).eval("self")
        # => X
        p binding.of_caller(1).eval("hoge")
        # => "hoge"
    end
end

class X
    def self.hoge
        "hoge"
    end

    A.hoge
end

binding_of_caller を使用することで『呼び出し元のコンテキストで式を評価する事が出来る』ので実現することが出来ます。
闇が深い…。

参照