OmniAICreator/Qiita-1.07M huggingface dataset:
rspec-givenを利用したGiven/When/Thenスタイルのテスト

## <i class='fa fa-cubes'></i> Given/When/Then とは？
Given/When/Then は BDDのテストを書く際に利用される記法です。
基本的な考え方として、テストを3つのセクションに分割して記載します。
これにより各ブロックごとの役割がひと目で分かり、可読性が高まることがメリットと考えられます。
（このスタイルが読みやすいと思わない人にはメリットになりませんね）

<!-- more -->

### <i class='fa fa-cube'></i> 1. Given
Given では振る舞いを実行する前の状態を記述します

### <i class='fa fa-cube'></i> 2. When
When では振る舞いを記述します

### <i class='fa fa-cube'></i> 3. Then
Then では振る舞いの結果を記述します

## <i class='fa fa-flask'></i> サンプル
RSpecで Given/When/Then スタイルのサンプルを書いてみます。
rspec はデフォルトでは Given/When/Then スタイルをサポートしていないので、
rspec-given gem を利用します。

### <i class='fa fa-wrench'></i> 設定
[rspec-given - GitHub](https://github.com/rspec-given/rspec-given)

```sh
$ gem install rspec-given
```

### <i class='fa fa-code'></i> コード
* プロダクトコード

```ruby
require "sample/version"
require "sample"

class Person
  attr_reader :name, :age

  def initialize(name, age)
    @name = name
    @age = age
  end

  def next
    @age = age.next
  end
end
```

* テストコード

```ruby
require "spec_helper"
require "sample"
require "rspec-given"

describe Person do
  context "#fullname" do
    Given(:person) { ::Person.new("tanaka", 32) }
    When { person.next }
    Then { person.age == 33 }
    And { person.name == "tanaka" }
  end
end
```

* 実行（成功）

```sh
$ rspec
.

Finished in 0.0012 seconds (files took 0.1706 seconds to load)
1 example, 0 failures
```

* 実行（失敗）

失敗するようにわざとテストを変更してみます

```sh
$ rspec
F

Failures:

  1) Person#fullname     Then { person.age == 34 }

     Failure/Error: Then { person.age == 34 }

       Then expression failed at /path/to/project/spec/sample_spec.rb:9
       expected: 33
       to equal: 34
         false   <- person.age == 34
         33      <- person.age
         #<Person:0x007f985410a2e0 @name="tanaka", @age=33>
                 <- person
     # ./vendor/ruby/2.3.0/gems/given_core-3.8.0/lib/given/rspec/framework.rb:24:in `fail_with'
     # ./vendor/ruby/2.3.0/gems/given_core-3.8.0/lib/given/module_methods.rb:42:in `fail_with'
     # ./vendor/ruby/2.3.0/gems/given_core-3.8.0/lib/given/extensions.rb:127:in `_gvn_naturally_assert'
     # ./vendor/ruby/2.3.0/gems/given_core-3.8.0/lib/given/extensions.rb:118:in `_gvn_evaluate'
     # ./vendor/ruby/2.3.0/gems/given_core-3.8.0/lib/given/extensions.rb:102:in `_gvn_then'
     # ./spec/sample_spec.rb:9:in `block in Then'

Finished in 0.01827 seconds (files took 0.14176 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/sample_spec.rb:9 # Person#fullname     Then { person.age == 34 }
```

## <i class='fa fa-book'></i> 文献
Given When Then に関する参考文献です

* [GivenWhenThen - martinfowler.com](http://martinfowler.com/bliki/GivenWhenThen.html)
* [Given When Then - Cucumber Wiki](https://github.com/cucumber/cucumber/wiki/Given-When-Then)
QWidgetの階層構造を可視化するデバッグ支援ツール


> [Qt Advent Calendar 2016](http://qiita.com/advent-calendar/2016/qt) 14日目の記事です。

QWidgetの階層構造を可視化するデバッグ支援ツール[WidgetBrowser](https://github.com/tetsurom/WidgetBrowser)を作りました。

# はじめに
大規模なアプリケーションの開発では、画面上に見えているウィジェットがどこで実装されているのかわからないということがしばしばあります。表示されている文字列で検索することもできますが、クラス名が分かればもっと効率よく該当ソースコードを探すことができます。

Qtでは、宣言中に`Q_OBJECT`マクロを含むクラスであればクラス名を知ることができるので、例えばカーソル下にあるウィジェットのクラス名を調べるということが可能です。

そこで、ウィジェットの階層構造を辿ってクラス名を調べられるツール[WidgetBrowser](https://github.com/tetsurom/WidgetBrowser)を開発しました。

![image](https://qiita-image-store.s3.amazonaws.com/0/31974/ee71af50-9df6-4d4f-8b16-051695682afc.png)

# インストール

基本的にアプリケーションに組み込んで使います。

[WidgetBrowser](https://github.com/tetsurom/WidgetBrowser)を`git clone`して`src/wb`ディレクトリをアプリケーション内にコピーし、ビルド対象に含めます。

起動するには`wb::WbDialog::exec()`を呼ぶだけでOKです。`WbDialog`クラスが自動的に`QApplication`オブジェクトから情報を集めて表示します。

```cpp:example
#include <wb/dialog.h>
⋮
wb::WbDialog dialog;
dialog.exec();
```

また、イベントフィルター `WbOpenListener` を`QApplication`にインストールすることでショートカットキーで起動できます。

```cpp:example
#include <QApplication>
#include <QKeySequence>
#include <wb/listener.h>
⋮
WbOpenListener listener;
listener.setKeySequenceToOpen(QKeySequence("Meta+F2"));
qApp->installEventfilter(&listener);
```

アプリケーションのソースコードを変更できない場合、WidgetBrowserを組み込んだQtのDLLを
ビルドして差し替えるという方法が使えます(対象がLGPL版Qtを使っていれば)。

# 使い方

起動すると、その時点のウィジェットの階層構造がキャプチャーされ、左側のツリーに表示されます。

トップレベルの要素は以下の5つです。

* Active Modal Widget  
    アクティブなモーダルウィジェット(`QApplication::activeModalWidget()`の値)
* Active Popup Widget
    アクティブなポップアップウィジェット(`QApplication::activePopupWidget()`の値)
* Focus Widget
    フォーカスを持つウィジェット(`QApplication::focusWidget()`の値)
* Widget at Cursor
    カーソル下のウィジェット(`QApplication::widgetAt(QCursor::pos())`の値)
* Top Level Widgets
    トップレベルウィジェット(`QApplication::topLevelWidgets()`の値)

これらは起動した瞬間の値であり、更新されません。

![image](https://qiita-image-store.s3.amazonaws.com/0/31974/5497dfe7-87b6-7c8a-5628-4a77d3853be8.png)

ツリー上でウィジェットを選択すると右側にウィジェットのスクリーンショットが表示されます。

ツリー上ではコンテキストメニューからウィジェットのクラス名をコピーできます。
スクリーンショット上では画像を保存できます。

ダイアログを閉じるとアプリケーションに処理を返します。

# 作り方

ツリービューは、ウィジェットの階層構造を表すアイテムモデルを作成して使っています。

* [QAbstractItemModelを実装してツリービューを作る(Read Only編)](http://qiita.com/tetsurom/items/acef221a06a2421e33d8)

スクリーンショットは、`QWidget::render`を呼ぶことで画像を取得しているため副作用があります。また、一度も`show()`されていないウィジェットは正しくない画像になることがあります。

```cpp
QWidget* widget;
QLabel* label;

const QRect rectangle(QPoint(), widget->size());
QPixmap pixmap(rectangle.size());
widget->render(&pixmap, QPoint(), QRegion(rectangle));

label->setPixmap(pixmap);
```

クラス名をコピーする機能は以下のように実装しています。
```cpp
void copyClassName(QWidget* widget) {
    QApplication::clipboard()->setText(widget->metaObject()->className());
}
```

# 欲しい機能
週末にハッカソンで作ったツールなので現時点での機能は少ないです。

QtDesignerのプロパティエディタ的な機能を付けたい。

![image](https://qiita-image-store.s3.amazonaws.com/0/31974/03f07dfd-8f95-72eb-c7a4-ee35feede911.png)

# まとめ
大きなプロジェクトでは検索のキーワードとしてクラス名を知りたいことがあるのでツールを作りました(おまけでスクリーンショットも付けてみました)。
MediaControllerをカスタマイズする(のを諦めてライブラリ作った)

## MediaControllerとは

[MediaController](https://developer.android.com/reference/android/widget/MediaController.html) とは、再生・早送り・シークといった、音楽や動画の基本的な制御を行うことのできるViewです。

MediaPlayerやVideoViewと連携して使うことができます。
[ExoPlayerの1.x時代のサンプルアプリの中でも](https://github.com/google/ExoPlayer/blob/release-v1/demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java#L105)使われていました。

こういうやつです。
![basic.png](https://qiita-image-store.s3.amazonaws.com/0/35511/aae7f15d-8ee3-4438-c6b3-1e2b9cc82ad6.png)


※Android SDK上には`android.widget.MediaController`と`android.session.MediaController`とで
2つあってややこしいのですが、今回触れるのは前者の方です。(後者はsupportもあるのでなおややこしい)

## MediaControllerの仕様と問題点
MediaControllerの仕様は以下のようになっています。

- 早送りボタンを押すと15秒移動
- 早戻しボタンは5秒移動
- 表示されてから3秒経つと自動で強制非表示
- ボタン画像はSDK同梱の古いもので固定
- 時間表示部分のテキストの色が絶妙(端末によっては視認できない)

しかしながら、これらの値は変更できるようになっていません。

あまりに使いづらいため誰も使ってないと思いきや、
[StackOverFlow で検索すると最近でも結構悲鳴が上がっている](http://stackoverflow.com/search?tab=newest&q=MediaController%20android) ので、
「機能としてはMediaControllerで十分だけど、数値の変更やViewの調整だけはしたい」という需要はあるんじゃないかと思いました。

## ライブラリ作りました
というわけでPlayerControlViewというライブラリを作りました。

https://github.com/ogapants/PlayerControlView

前述した問題を解消できるように、基本機能はMediaControllerのままで書き直しました。
一例ですが、見た目の変更すると以下の感じになります。

![custom.png](https://qiita-image-store.s3.amazonaws.com/0/35511/616650e8-56c6-490a-7ce6-e192f5923e9a.png)


### 基本的な使い方

PlayerControlViewでは[MediaController.MediaPlayerControl](https://developer.android.com/reference/android/widget/MediaController.MediaPlayerControl.html)をプレイヤーとして使うようにしています。

```java
PlayerControlView playerControlView = new PlayerControlView(this);
playerControlView.attach(this);
playerControlView.setPlayer(/* mediaPlayerControl */);
```

MediaControllerでは以下のように書くので、なるべく移行しやすいように計らいました。

```java
MediaController mediaController = new MediaController(this);
mediaController.setAnchorView(/* view */);
mediaController.setMediaPlayer(/* mediaPlayerControl */);
```

ExoPlayer1.xではMediaPlayerControlをラップした[PlayerControl](https://github.com/google/ExoPlayer/blob/release-v1/library/src/main/java/com/google/android/exoplayer/util/PlayerControl.java#L27)というクラスがあるため、それを使うことでプレイヤーとして利用できます。
Javadocで`not require this class.`と書かれてますけど使わせてもらいました。

カスタマイズ方法についてはGitHubのREADMEやサンプルを見ていただけたらと思います。

## ターゲット
- MediaPlayer
- VideoView
- ExoPlayer1.x

現状この3つのプレイヤーはサポートしています。
今からちゃんと音楽や動画をやるならExoPlayer2を使うことになると思いますが、
カジュアルにやるならまだ彼らはまだ活躍するでしょうし、
カジュアルだからこそプレイヤーの見た目は用意されたやつでいいってこともあるんじゃないでしょうか。
(LINEの動画再生部分はほぼMediaControllerですし…)
そんな中でMediaControllerじゃアカンというときには、この記事のことを思い出していただけたらと思います。

これ以上のレイアウト変更や機能の追加をしたい場合は独自で作りましょう。

ちなみにExoPlayer2では[PlaybackControlView](https://github.com/google/ExoPlayer/blob/release-v2/library/src/main/java/com/google/android/exoplayer2/ui/PlaybackControlView.java)というMediaControllerのような見た目のViewが使えるようになりましたが、ExoPlayer2そのものに依存しているため他のプレイヤーでは使えません。
尚、PlaybackControlViewの方はViewの変更はできませんが、早送りなどの時間の変更は可能です。

## おわりに
この記事の内容は[2016年の6月に行われた kyobashi.dex](https://rmp-quipper.connpass.com/event/31744/)で[LTしたもの](https://speakerdeck.com/ogapants/mediacontroller-wokasutamaizusuruzo)ですが、ライブラリの公開まではしてない状態でした。
あれから色々ありましたが2016年中に公開できてよかったです。（小並感)

現場からは以上です。
Xamarin.Androidで作ったアプリ内で画像を保存する時の話

#はじめに
Xamarin.Androidでアプリ開発した時、アプリ内で内部ストレージに画像保存する時についての資料があんまりなかったので、忘れないようにの**備忘録**です。
内部ストレージに画像保存でググると大抵Java.IOとSystem.IOあたりで詰まってしまうので、そんな方向けにも。~~調べ方が悪かったかもだけど~~
私自身まだまだ知識不足なところがあるので、細かい指摘などお待ちしております。

#どんな時に読んで欲しい
Xamarinで作ったアプリ内で画像保存したい。でもその画像あとでギャラリーアプリとかで見たい。
しかしどうすればいいかわからない。Sysytem.IOとJava.IOとかで積んだ。そんな人向けです。

#Xamarinで作ったアプリ内で画像を保存する時
*今回はSDカードとかの外部ストレージではなく、内部ストレージに保存するという前提です。*
なのでパーミッション`WRITE_EXTERNAL_STORAGE`を忘れずに。

```C#:ImageSave.cs
Bitmap bitmap; //保存したいBitmapが格納済み

//保存する画像の名前を決める
String imgname = "img_";
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddkkmmss");
imgname += sdf.Format(date);
imgname += ".png";

//保存先のパスとか      
ContextWrapper cw = new ContextWrapper(this.ApplicationContext);
Java.IO.File file = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDcim);
Java.IO.File myfile = new Java.IO.File(file, imgname);

//保存
using (var os = new System.IO.FileStream(myfile.AbsolutePath, System.IO.FileMode.Create))
{
 bitmap.Compress(Android.Graphics.Bitmap.CompressFormat.Png, 100, os);
 }


```
保存する際、画像の名前を決めるコードは[ここ](http://mizusoba.blog.fc2.com/blog-entry-74.html)から引用させて頂きました。

###保存先のパス
今回保存先をわかりやすいように、内部ストレージのDCIMに保存することにしました。データディレクトリじゃないのは、一応画像処理された画像の保存なのでMyPicture的な所が良かっただけです。
この画像の保存先のパスの取得に詰まりました。

```
Java.IO.File file = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDcim);
```
Android.OS.Environment.DirectoryDcimの所でMyPictureとか色々と指定ができると思います。

###画像の保存

```
using (var os = new System.IO.FileStream(myfile.AbsolutePath, System.IO.FileMode.Create))
{
 bitmap.Compress(Android.Graphics.Bitmap.CompressFormat.Png, 100, os);
 }
```

Javaだと`FileOutPutStream`などでJava.IOとSystem.IOの変換などが出来ないとかで色々と悩まされました。
System.IO.FileStreamというのがあったなんて。。。

#参考サイト
[android - How to save an image to Internal Storage and then show it on another activity? - Stack Overflow](http://stackoverflow.com/questions/23131768/how-to-save-an-image-to-internal-storage-and-then-show-it-on-another-activity)
[家の前にかむ犬がいた Intentでアプリ内画像をtwitterとかに送る](http://mizusoba.blog.fc2.com/blog-entry-74.html)
家系ラーメンで学ぶ新規ゲームの企画書

# はじめに

この記事は[gloops Advent Calendar 2016](http://qiita.com/advent-calendar/2016/gloops)の14日目の記事です。

エンジニアの山田です。

理想としては**届いたばかりのOculusTouchでこんなの作ってみた**的な記事にしたかったのですが、社内の新規ゲーム企画コンペに応募する企画書の作成が順調に遅れてしまったため、叶いませんでした。悲しみ。。

代案としては**僕はこうやってUnityを覚えた**的な記事にしようかと思ったのですが、ありきたりでインパクトないしどうしようかなーと思いつつ企画書を書いていると、突然、**新規ゲームの企画書の内容って家系ラーメンで説明できるのでは?**と閃いたので記事にすることにしました。

今後もし僕みたいにエンジニアだけど新規ゲームの企画書を書くといった機会があった際には参考になるかもしれませんがならないかもしれません。

# 新規ゲーム企画書に書く内容
新規ゲーム企画書には以下の内容が必要です

- **コンセプト**
    - 一言で説明するならどんなゲームか 
- **世界観**
    - ゲームの舞台となる世界はどんな世界なのか、どんなキャラクターが存在するのか
- **ターゲットユーザ**
    - どのような属性の人がこのゲームを気に入ってくれるのか
- **構成要素（機能）**
    - ゲームの機能として何があるのか（バトル、編成、ガチャ、ギルドなど）
- **ゲームサイクル**
    - ゲームの機能同士がどのように関わっているのか（ガチャでキャラクタを入手して編成でパーティを組んでバトルするなど）
- **レベルデザイン**
    - ユーザが初級者 -> 中級者 -> 上級者とゲームを進めていく上で、どのように成長するのか
- **UI**
    - 世界観や構成要素に沿ったデザイン
- **マネタイズ**
    - どうやって売上を上げるのか

これらを家系ラーメンで説明します。

# コンセプト

とんこつベースの醤油味の濃厚なスープに中太麺を使い、海苔とほうれん草をトッピングしたラーメン
ライスとよく会う
卓上の調味料で味を自在に変化できる

# 世界観
神奈川県横浜市を発祥とする。
発祥の店は工場地帯に立地していたため、工場労働者やトラック運転手の間で評判になっていった。
発祥の店から弟子が独立していき、同様のラーメンが広まった。
ラーメン屋の屋号に「～屋」とついているところが多かったところから家系と呼ばれるようになった。
店員はタオルのねじり鉢巻、半袖の白Tシャツに白いパンツに長靴といったスタイルで元気の良い男性店員が多い。

# ターゲットユーザ
10代～40代男性
濃厚なラーメンを好む人
主に関東地方出身者もしくは関東地方在住者


# 構成要素（機能）
- ラーメンスープ
    - 豚骨醤油
    - 塩
- ラーメン注文時のカスタムオーダー
    - 麺の硬さ（柔らかい/普通/硬い）
    - スープの濃さ（薄い/普通/濃い）
    - 油の量（少なめ/普通/多め）
- トッピング
    - 味玉
    - のり
    - うずら卵
    - ネギ
    - ほうれん草
    - チャーシュー
- サイドメニュー
    - ライス
    - ビール
- 卓上の調味料
    - すりおろしニンニク
    - 針生姜
    - 豆板醤
    - ごま
    - コショウ
    - 酢

# ゲームサイクル

## 注文時
設置されている券売機を利用する
ラーメンスープとトッピング、サイドメニューを選択する
店員に食券を渡す際にラーメン注文時のカスタムオーダーを口頭で伝える

## 食事中
卓上の調味料を随時ラーメンに追加する
トッピングやサイドメニューは食事中でも追加注文することができる
カスタムオーダーの内容によっては食事中でも変更できる


#レベルデザイン
最初はラーメンに何も入れずにそのまま食べる。
次に卓上の調味料やトッピングや麺の硬さなど、自分の好みの味を探していく。
卓上の調味料やトッピングには複数組み合わせがあるため、一度では全てを試すことができないため、次回は違う組み合わせを試してみたくなる。
スタンプカードを使用することで継続率を上げる。

## 初級者
ラーメンを全てを普通で注文する
何も入れずにそのまま食べる

## 中級者
ラーメンを麺硬めで注文する
卓上の調味料を「お店のおすすめ」と書いてある方法で入れる
もしくは「通の食べ方」と紹介されている方法で入れる

## 上級者
ラーメン注文時に「硬め、濃いめ、普通で」と言いながら注文する
店員に顔を覚えられる
「今日のスープはいまいちだったな」などと言いながら退店する

# UI
太字のフォントと原色を使用した力強いデザインにする
既存の家系ラーメンと系統を揃えることで、新規開店時にもユーザに家系ラーメンだと認知してもらいやすくなる

# マネタイズ
基本はラーメン
上級者向けにトッピングやサイドメニューも用意する

#おわりに
何かを別な何かで例えることって実は結構重要なのではないかと感じています。

知らない人に説明する際に例えを使うことで理解してもらいやすくなります。
エンジニアが非エンジニアの人に説明する機会はよくあるのではないでしょうか。

また、例える元の内容をちゃんと理解していないと例えることができません。
いい感じに例えようとしてうまくいかない時は、自分の理解が間違っている可能性があります。

普段から自分の知っていることを何かに例えるトレーニングをしておくと、物事の本質を捉える力が身につくかもしれません。
また、これってどういう意味だっけ?と思ったときには、他のもので例えるならどうなるだろうと考えると、道が拓けるかもしれません。
Hashだったらキーの値、nilだったらnilがほしいとき

Hashインスタンスかnilか分からない変数があって、Hashインスタンスだったらキーに紐づく値がほしい、nilだったらnilのままでいい、そんなコードが書きたくなることがある。

単純に書くと下記のようになるが、変数名を2度書くのが面倒だ。

```ruby
a = {foo: 1}
b = a ? a[:foo] : nil
b = a && a[:foo]
```

Ruby 2.3.0以降なら「ぼっち演算子(safe navigation operator)」が使える。

```ruby
b = a&.[](:foo)
```

NilClass#to_h で {} が返るので、下記のようにする手もある。

```ruby
b = a.to_h[:foo]
```
Hugoでタグやカテゴリのリンク切れが起こる

#Hugoでタグのリンク切れが起こる
どうやらHugoではtagのURLは英数字の場合小文字でしかアクセスできないようです．

#解決方法
```:markdown
{{ with .Params.categories }}
   <div class='SingleArticle__Category'>
      {{ range . }} <a href="/categories/{{ lower . }}/">{{ . }}</a>{{ end }}
   </div>
{{ end }}

{{ with .Params.tags }}
   <div class='SingleArticle__Tags'>
      {{ range . }} <a href="/tags/{{ lower . }}/">{{ . }}</a>{{ end }}
   </div>
{{ end }}
```
このようにリンクの部分は`{{ lower . }}`と記述すると解決します．
***

日本語のタグは問題なく使えるので全然気づかなくて困りました．
大文字が使われているタグやリンク切れになってるHugo製のブログや，英数字を全て小文字にしているブログをよく見るので，参考にしてください．
RxJava初心者によるRxJavaのすゝめのす

こんにちは、[ディップ Advent Calendar](http://qiita.com/advent-calendar/2016/dip-dev) 14日目の担当者のものです。大屋です。

業務ではAndroidアプリを担当してます。けどiOSとかもやってたりします。
春からJava言語を勉強を開始してAndroidアプリを作ってます。

そんな日々の業務の中でよく聞くRxJava...

名前は良く聞くけど一体何なんだろう？

今回はRxJavaについて素人目線で色々調べてみましたのでまとめたいと思います。
宜しくお願い致します！！

# RxJavaとは...

まずはRxJavaとはなんぞや？について、

RxJavaはJavaでリアクティブプログラミングをする為のライブラリです。また、このライブラリは軽量で、他のライブラリとの依存関係がないことから気軽に使える利点があります。

# リクティブプログラミングとは...

続いてはリアクティブプログラミングについてです。
リアクティブプルグラミングはデータの流れに着目したものになっています。スマホアプリ開発の場合は画面の生成時や破棄するときにコールバック関数が用意されていますが、リアクティブプログラミングのわかりやすい例としてGPSがあります。GPSは、その持ち主の位置情報が更新されればデータが送信され、立ち止まるとデータの送信はストップします。このように、特定のイベントに対してロジックを実行するのではなく、データが生成された時点で処理が始まるのがリアクティブプログラミングと言えます。

リアクティブプログラミングにより実装することの利点は、先ほど説明したデータの送信者とデータの受信者で処理を分けてコーディングできることから無理なくデータストリームを扱えることができる点が挙げられます。

# ObservableとObserverについて...
データの送信と受信を分けて記述できると先ほど説明しましたが、リアクティブプログラミングではデータを送信するオブジェクトをObservable、データを受信するオブジェクトをObserverとして取り扱います。また、データを送信するObservableをObserverが購読（subscribe）することによりObserverはデータを受け取ることができるようになります。

# 最後に

今回の記事ではRxJavaとリアクティブプログラミングについてザックリと説明しました。次回は簡単なデモをしながら記事をまとめますので宜しくお願いします。
MySQLでINSERTができなくなった？


## 経緯
筆者はDBAではなく、多少RDBを触るWEBデベロッパ。

100GB程度のデータを持つDBサーバのリプレイスのため、新規にMySQLをセッティングし、mysqldumpで取得したデータをリストア。データ量が多いのでなんとか少しでも早めようとmy.cnfに設定を多少追加。

リストア自体は完了。

その後、テスト用のアプリケーションをつなぎこんでテスト運用開始。データが追加されず。
データが追加されず？


## エラーがない。

データが追加されないとうことは、一般的には「エラー」があるために処理が停止している可能性が高い。
基本通りにアプリケーションのログ、MySQLのログを確認するもエラーはない。
兎に角、エラーと確認できるログはない。
手詰まり。

仕方なく、コンソールにてINSERT文を発行してみる。
データが__追加されない__。

データが追加されない！INSETできない！

しかし、これもエラーにならない。
しかも、同じコンソールでSELECTすると、なんとデータがある！！
他のコンソールからは見えないのに？


## ？？？

DBAでない筆者は若干パニックになったので、喫煙者の特権である休憩をとることにした(VAPEだが)。
データはINSERTできているように見えて、実際にはINSERTできていない。
そもそもINSERTってなに？と、余計方向性が怪しくなりゲシュタルト崩壊気味。

commitしてないのでは？と、はたと気づいた。
今までそれほど一生懸命はMySQLを勉強していなかったのを反省。


## 原因

弱小システム屋には大きめのデータ100GBのDBをリストアするため、多少でも時間を節約できればとGoogle検索。行き着いた先の設定が下記。

```my.cnf
[mysqld]
init_connect='SET AUTOCOMMIT=0'
```

自動的にcommitしない、という設定。
詳細は[こちら → MySQL 5.6 リファレンスマニュアル  /  START TRANSACTION、COMMIT、および ROLLBACK 構文)](https://dev.mysql.com/doc/refman/5.6/ja/commit.html)

(なお、MySQL5.5.8以降では、my.cnfに`autocommit=0`で設定できる)

mysqldumpでバックアップをとりリストアする際に、SQL文の行数が多いと、その都度commitが発行されるので遅くなると。
そして、これを一回のcommitで処理するために上記の設定を行うと、かなり速度が改善されると。

結局、リストアしたデータのカラムに巨大なデータを含むものがあるからか、100万行なぞ大した量でないのか、たいした速度の変化は感じられなかった。
思うに、tableが大量にある場合などには効果的なんだと思う。

で、上記の設定を放置。

そう、commitしていないから。データ登録されてないのね。
commitって要るんだね。

## 対応

上記の設定を削除してMySQLを再起動。無事データがINSERTできました。
alpineにmecabをインストールするときに文字化けする対策

# mecabをインストールする方法
macならbrew、cent osならyumなど便利なインストール方法があるが、訳あってalpineをベースイメージにしたDockerコンテナ上にmecabをインストールする必要があったのだが、ネットに転がっている記事で試すと実行結果が文字化けするので、ここにまとめておく（とはいえ、実施後少し時間が経っているので間違えていたらごめんなさい）

【参考】 [さくら共有サーバー、UTF-8の辞書でmecabを使う方法](http://nymemo.com/sakura/258/)

## mecab本体のインストール
本家サイト通りに行う
## 辞書のインストール（ココ）
  1. インストール先のディレクトリを作成

    ```
    /home/local/mecab-dic/ipadic-utf8
    ```
  2. 辞書のダウンロード及び解凍
  3. 辞書のインストール

    ```
    ./configure --with-charset=utf8 --with-dicdir=~/local/mecab-dic/ipadic-utf8
    make
    make install
    ```
  4. 辞書の紐付け

    ```
    mecab -d ~/local/mecab-dic/ipadic-utf8
    ```

***
これで、無事mecabがUTF-8で使えるようになったらしい。
細かいところ追いかけていないが、どうやら標準のインストール先に入れるとどうもだめらしい。
Amazon LightsailでRadmineインスタンスを作成する。

[AWS Lightsail](https://aws.amazon.com/jp/blogs/news/amazon-lightsail-the-power-of-aws-the-simplicity-of-a-vps/)というAWSのVPSサービスがリリースされたので早速つかってみた。
本当にただ使ってみただけ。

ちなみに今回作るのはRedmine。ちょうどプロジェクト管理するものが欲しかったので。

## インスタンスを作成する
以下のようにパッケージングされたインスタンスを選んで
![Lightsail_create_instance.png](https://qiita-image-store.s3.amazonaws.com/0/134199/0ba3162a-d890-d5cc-3e02-3470378d1d80.png)

赤い下線のところでキーペアを作って（あるいは選んで）
※デフォルトキーペアが最初は表示されるみたい
![Lightsail_create_instance2.png](https://qiita-image-store.s3.amazonaws.com/0/134199/251f476e-646f-0493-9a95-04748919eaef.png)

Createボタンをクリックするだけ。
最初は＄10が選ばれてるので＄5を選びなおしました。

##作成したインスタンスを確認する

だいたい3～5分程度でインスタンスの起動まで完了。

![Lightsail_instance.png](https://qiita-image-store.s3.amazonaws.com/0/134199/5065e946-8f39-e750-5049-3245c1ef9daf.png)

上のマシン名をクリックすると以下の情報が表示されます。

![Lightsail_instance2.png](https://qiita-image-store.s3.amazonaws.com/0/134199/b4fc04c1-5392-8f0e-552c-d51e7702d325.png)


黒く塗りつぶしているところにPublic IPやユーザ名が表示されるのでSSHで接続します。
接続にはインスタンス作成時に作った（あるいは選んだ）キーペアを使ってログインできます。

##肝心のRedmineは起動しているのか？

普通に起動してた。
Public IPにアクセスしたら接続できました。

![redmine_interface.png](https://qiita-image-store.s3.amazonaws.com/0/134199/0389b93b-11b8-9ce5-41bc-eab328b85c89.png)


よく確認したらインスタンスのNetworkingタブで80番が空けられてました。

![instance_netwoking.png](https://qiita-image-store.s3.amazonaws.com/0/134199/8aa37140-0af2-632d-cbd3-4bcaa2087fd5.png)


##Redmineのログインユーザとパスワード

[bitnamiドキュメント 「How To Find Application Credentials?」](https://docs.bitnami.com/aws/faq/#how-to-find-application-credentials)にユーザ名は書いてあります。
なお上記のページに初期パスワード確認方法が記載されています。
ドキュメントを見る限りEC2初回起動ログにパスワードが表示されているので、それを確認するようですが、LightsailはEC2インスタンスではないので初回起動ログを確認できません。

実はインスタンスにsshでログインした後、以下の場所にパスワードが記載されたファイルがあるようです。

```
$ pwd
/home/bitnami
$ ls
apps  bitnami_application_password  htdocs  stack
$ cat bitnami_application_password
***************
```

これで無事ログインできました。

以上。
実践ピアプレッシャーによる継続的肉体開発

皆さん、身体鍛えてますか？💪


私自身、学生時代はそこそこ運動していたのですが、
やはり社会人になってからは運動する機会は減り、
体重はどんどん増えていきました。

たまに運動を始めても仕事が忙しくなったら
また運動するのを忘れ、その結果リバウンドを繰り返すという悪循環です💀

そんな中最近知人にお誘いを受けて始めたトレーニングが
思いの外続いているのでそのトレーニング方法について書かせていただきます。

#ピアプレッシャー
タイトルにもあげたピアプレッシャーについて、簡単に説明すると

```
二人以上の人数で鍛える部位を素手で力いっぱい
圧迫しつつ運動を行う加圧トレーニングの一種です。
```

**嘘です🙏🏼**

本当は以下の通りで互いにプレッシャーを掛け合う事の事を指します。

```
「仲間からの圧力」という意味。例えば、日本企業の特徴は「仲間との和」を重んじる家族主義的な経営。そのような環境では「仲間に迷惑はかけられない」「仕事が遅れたら申し訳ない」といった心理が働く。そのことが仲間との協力関係を醸成し、大きな成果に結びつく。一方、この傾向が行き過ぎると、互いが監視し合う居心地の悪い環境になり、ストレスの温床になると言われる。最近では日本的経営を取り入れた海外企業でも、日本の国内企業と同じようにプラス効果とマイナス効果が顕在化しつつあるという。
```
http://yougo.ascii.jp/caltar/ピアプレッシャー より抜粋

結論から言うと **一人でやらずにみんなで監視し合いながら筋トレすると続くよ** っていう
あまり新鮮味のない話に落ち着いてしまうのですが、
実際やってみてる内容について具体的に書いていきますね。

#日々のトレーニングの様子
トレーニングは以下のように行なっていきます。

- トレーニングの時間は自由
- トレーニングのメニューは自由
- 毎日何かしらの運動をする事
- メニューは固定でなくてもよい

実際にトレーニングの内容を報告しあってる内容のキャプチャです。
雰囲気が伝わるといいのですが。
![log.png](https://qiita-image-store.s3.amazonaws.com/0/11776/150037a3-d2be-1fd3-c601-a6483c443314.png "log.png")

そんな感じで今も継続してトレーニングを続けています。
やり始めて1ヶ月が過ぎましたがまだまだ元気に続けていけそうです。
![IMG_1589.PNG](https://qiita-image-store.s3.amazonaws.com/0/11776/4c996cf9-35ae-77bd-f8e7-f7cbe2e7b1bc.png "IMG_1589.PNG")



#使用してるツールについて
私は今「みんチャレ」を使用させてもらっています。
個人的には5人1グループという人数制限が絶妙にコミュニケーションを
機能させているのではないかと思います。
Slackなどでもいいですがメンバが多いと
プレッシャーが薄れる事もあるのかなというのが個人的な感覚です。
https://minchalle.com/a/

また、AppleWatchを持ってるメンバ同士では
Activityを共有するなどをして日々の消費カロリーなどが
互いにわかるようにしたりもしています。

#まとめ
このように個々のレベルがバラバラな中でもこのように互いに互いのベストを尽くし、
時に教えあい、時に煽り合い、称え合う環境があれば中々楽しく筋トレを
続けていけるのではないかと私は考えています。
(筋トレに限らず勉強なども含めたトレーニング全般にも言えるんですけどね)

我々はエンジニアですから、基本的に継続的開発を行うのは慣れています。
普段の流儀に合わせてビルドしたり計測したり解析したりレビューしたり、
時には肉体のコンディションを見ながらメニューをアジャイルに変えていき
楽しく肉体をリファクタリングしていきましょう💪
リリースタイミングは自身のステークホルダに委ねてください。(?)

##おまけ
###腹筋ローラー
私は普段家でトレーニングする時は自重だけにする事が多いのですが、
使用器具としては腹筋ローラーで立ちコロするのが大好きです。
腹筋ローラー自体は格安で手に入る割に負荷が高く、
この寒い時期に朝起きて体を暖めるにはとても都合が良い器具ですね。
膝コロ？それは自転車に補助輪ついてるのと同じなのでさっさと立ちコロしましょう！
伸ばしきった状態から「ビターン！」となるって人は多いと聞きますが、
1回立ちコロが出来てしまえばあとは自転車に乗るのを覚えたように使う筋肉を
意識出来るようになるので続けて2回、3回と出来るようになります。
漢なら立ちコロです。

###スクワット前蹴り
空手時代からやるのですが、スクワット1回毎に前蹴りを全力で打つだけです。
「全力で打つ」を意識しましょう。普通のスクワットに慣れた人は気分転換に
お試しあれ。
footerFixed.jsの改造

footerFixed.jsの少し残念なところは、直前の要素と隙間ができてしまって直前の要素に枠線や背景色があると、それはそれで見栄えが悪くなるところだ。またbodyのマージンを無視してウィンドウの下端に張り付くのが気になるときもあるかもしれない。 そこでそのあたりを改造してみた。

http://qitailang.small.jp/misc/fixed_footer2/
Ansibleをポータブルに利用する2つの方法

# はじめに

Ansibleでサーバ構成管理を行うのには、構成対象にsshできるマシンに環境構築する必要があります。
ですが、こんな場合があるかもしれません

- インターネットに接続できない
- 勝手に新規ソフトウェア入れられない

こんなときに、インストールなしでAnsibleを利用したいことがあります。
つまり以下のようなことがやりたいことです。

```
                  |→プロダクト環境   
                  |    ★この環境は中々いじれない。。
┌─────────────┐   |   ┌─────────────┐       ┌───────────────┐
｜1           ｜  |   ｜ 2          ｜      ｜ 3            ｜
｜            ｜──────｜            ｜──────｜              ｜
｜            ｜  |   ｜            ｜ssh   ｜              ｜
└─────────────┘   |   └─────────────┘       └───────────────┘
ローカルマシン     |    Ansibleサーバ           構成対象サーバ

→Ansibleサーバーにはディレクトリ転送するだけで、ansible使いたい！
```

というわけで、
ローカルマシンでゴニョゴニョしたら、あとはディレクトリ転送だけでAnsible実行可能とする方法を2つ紹介します。
※ローカルマシンはインターネット接続可で自由にソフトもインストール可能という前提です。

# 1. gitからソースをダウンロードする方法

これは、Ansibleのドキュメントにも載っているので知っている方も多いかもしれません。

## ローカルマシンでの手順

まずは`git clone`します

```bash
git clone https://github.com/ansible/ansible.git --recursive
```

こんな感じに、ansibleディレクトリができます。

```bash
$ ls
ansible
```


サブモジュールをアップデートします。
※これをやらないと怒られるみたいです。

```bash
cd ansible
git submodule update --init lib/ansible/modules/core
git submodule update --init lib/ansible/modules/extras
cd .. #元のディレクトリに戻っておく
```

これで準備は完了です。
`ansible`ディレクトリ(とPlaybook)をAnsibleサーバに転送します。

```bash
scp -r ansible [Ansibleサーバ]:
```

## Ansibleサーバー側利用方法

```bash
cd ansible
source hacking/env-setup
```

これで、ansibleのコマンドが実行可能となります。

## この方法が使える条件

以下の条件でないと動作しないようです。

- Python2.6 or Python2.7 がインストール済み
- pip paramiko PyYAML Jinja2 httplib2 six が導入済み

2点めが少しハードル高そうですね。。


# 2. PyEnv環境ごと転送

PyEnvで作成されたディレクトリをまるごと転送することで、環境構築しちゃおうという多少強引な方法です。

## ローカルマシンでの手順

まずはAnsibleを実行するディレクトリを、Ansibleサーバー側と同じパスで作成します。

例: Ansibleサーバーのユーザー名がopuserでAnsible実行ディレクトリ`ansible`を`/home/opuser`に置く場合

```
# useradd opuser
# su - opuser
$ echo $HOME  # => /home/opuser
$ mkdir -p /home/opuser/ansible
```

Ansible用ディレクトリにPyenvを環境を構築します。

```bash
cd /home/opuser/ansible
git clone https://github.com/yyuu/pyenv.git pyenv

touch ./pyenv.env
echo 'export PYENV_ROOT="/home/opuser/ansible/pyenv"' >> ./pyenv.env
echo 'if [ -d "${PYENV_ROOT}" ]; then' >> ./pyenv.env
echo '    export PATH=${PYENV_ROOT}/bin:$PATH' >> ./pyenv.env
echo '    eval "$(pyenv init -)"' >> ./pyenv.env
echo 'fi' >> ./pyenv.env

source ./pyenv.env

cd $PYENV_ROOT/plugins
git clone https://github.com/yyuu/pyenv-virtualenv.git
```

PythonをPyenv環境にインストールします。
その後、Ansibleをインストールします。
他にもインストールしたいパッケージがある場合はインストールします。
※バージョンはお好きにどうぞ

```bash
cd /home/opuser/ansible
pyenv install 2.7.12
pyenv local 2.7.12
pip install ansible
```

ansibleディレクトリを転送します。

```bash
scp -r /home/opuser/ansible opuser@[Ansibleサーバ]:
```

## Ansibleサーバー側利用方法

Pyenvの環境変数を読み込んでおきます。

```bash
cd ~/ansible
source pyenv.env
ansible --version #=> ansibleが利用できるようになっているはずです。
```

動作条件としては以下です

- ローカルマシンとAnsibleサーバでCPUアーキが一緒であること  
  ※例えばAnsibleサーバがx86_64ならローカルマシンもx86_64にする
- pyenvのパスがローカルマシンとAnsibleサーバーで同一であること

# まとめ

変更の影響を最小限に抑えたいプロダクト環境などでAnsibleを利用したい場合を想定して、
ポータブルなAnsible実行環境をに作成する方法を紹介しました。
定時退社したい！効率よく作業をこなすためのスケジュール管理

これは<a href="http://qiita.com/advent-calendar/2016/mynet">マイネットエンターテイメント Advent Calendar</a> 14日目の記事です。
<a href="http://qiita.com/hazama-mynet">hazama-mynet</a> がお送りいたします。<a href="http://mynet.hatenablog.com/entry/think_engineer_carrier">1日目の記事</a>でいうと『使ってくれるユーザーさんの喜ぶ姿が見たい、という思いが強いタイプ』のエンジニアです。
# はじめに
エンジニアは開発工程で最後のケツ持ちをすることが多いです。〆日から逆算して作業を前もって行ったり、スケジュール通りに行かなかった部分の帳尻合わせをしたり...
なんだかんだ、最もスケジュール管理の力が必要とされる職種と言って間違いないでしょう。今回はそんなエンジニアのスケジュール管理について、自身の考え方を含めて書かせていただきます。

<B>前提</B>

- Webサービス開発を行うことを想定しています

# 振り返ってみる
開発が始まって日にちは進んでいきますが、仕様が決まっていなかったり、別の作業が差し込んできたり...
<b>気付けばもう開発期間がない！</B>
こんな経験はありませんか？

ええ、大いにあります。

このとき、何がダメだったのか、どうすれば良かったのか、思い出せるでしょうか。今の作業がその繰り返しになっていませんか。決められたスケジュール通りに作業するだけになっていませんか。それは、決してスケジュール管理ができているとは言えません。
<div align="center"><img src="https://qiita-image-store.s3.amazonaws.com/0/150555/770727a1-ff3c-405a-4f45-8774c0c4cef8.jpeg" title="スケジュールをミスった ［モデル：古性のっち］"></div>
# スケジュール管理とは
<b>『自身がこなせる作業量を把握し、与えられた作業に対して、是非の判断を行うこと』</B>です。
開発初期に提示される決められたスケジュールは、全体を管理する人の"出来たらいいな"であり、正確なものではありません。唯一正確なのは開発の〆日です。工程を担当する各パートが〆日を元にスケジュールを提示し、すり合わせを行うことで本当のスケジュールができます。
決められたスケジュールに対して、是非の判断を行わず、そのスケジュール通りに進めることを選んだ時点で、完了させることが必然となります。この場合、スケジュールがキツいなどと言うことは論外です。なぜなら、それを自身で選んで、完了させることが必然になっているからです。
# スケジュール管理のステップ
スケジュール管理をするために、いくつかのステップがあります。このステップを何度も重ねることによって、より正確なスケジュール管理を行えるようになり、開発がスムーズに進みます。
### ステップ１
Webサービス開発を行う際、いつまでに、どのようなものを制作するか、最低限の情報はあるかと思います。その情報を元に逆算して、実装に必要なもの、それらが揃った上でできうるものを提示するのがスケジュール管理の最初のステップです。どのようなものを制作するかが決まっていなかった場合、担当者に作成を求めることもこのステップに含まれます。
### ステップ２
Webサービス開発はアジャイル型開発を採用していることが多く、短いスパンで追加実装ができるため、仕様を細かく分けることが可能です。
開発初期で提示される決められたスケジュールでは、制作する予定のものを実装する期間が足りない場合があります。その場合に制作する予定のものを細かく分け、次の期間に一部実装するなどの折衷案を提示するのがステップ２です。
### ステップ３
ステップ１、ステップ２を行い、決められたスケジュールではなく、自身が作ったスケジュール通りに実装を行い、実装を進める上で思った以上に作業が進んだ、または遅延した場合にその原因を考え解決していく。そうして自身のスケジュール感を研ぎ澄ましていくことが最後のステップです。
<div align="center"><img src="https://qiita-image-store.s3.amazonaws.com/0/150555/9da99cb4-090e-22dd-843d-d559bdf18f55.jpeg" title="モゥーひと頑張り ［モデル：古性のっち］"></div>
# スケジュール感を養う方法
スケジュール管理する上で、スケジュール感を養うことは非常に重要です。スケジュール管理のステップ１で提示するスケジュールを正確なものにするために、各作業にどれだけの時間が必要かというのを把握する必要があります。スケジュール感を養うために以下の点を意識しておくと良いです。
### 1. やるべきことを書く
朝、今日やるべき作業書き出します。新しく作業が入ってきた場合にもこれに追加します。やるべきことを把握することで、手をつける前に前もって何が必要かを考える癖がつきます。また、やるべきことを書くことで作業忘れを防止することもできます。
### 2. 優先度をつける
やるべきことに優先度をつけます。優先度が高いものから処理していくのですが、作業をやるときは手をつけたものが完了するまではそれを継続します。優先度が非常に高いものがきた場合は、現在の進捗状況とを天秤にかけて判断します。人間は１つのことを集中的に行った方が能率も高いため、できる限り手をつけたものが完了するまでは他のことをしない方が良いです。
### 3. 作業量を測る
これが最も掴みにくいです。なぜなら、やったことがない作業の作業量を見積もるのは難しいからです。新しい作業を行う際はどれくらいの時間がかかるかを想定しておき、それに対して実装完了時にどれだけの差異があったか、その差異はなぜ起こったのかを見直します。そうしてどんどんと精度を上げていくしかありません。
# まとめ
技術的な話ではなく、考え方の話となってしまい申し訳ありません。
スケジュール管理はエンジニアだけでなく、どの職種にも当てはまるとても重要なスキルです。初期段階でスケジュールをすり合わせておくことで、制作が終わったときに遅延のボトルネックがどこにあったのか、次はどう改善すれば良いのかも見えやすくなります。この記事内に少しでもお役に立てることが書けていれば幸いです。
<b>効率よく作業をこなせるスケジュール管理をして、定時に退社しましょう。</B>
<div align="center"><img src="https://qiita-image-store.s3.amazonaws.com/0/150555/d13e3b5c-3650-a3a6-7ddb-474ac3b11510.jpeg" title="金曜日17時 ［モデル：古性のっち］"></div>
最後までおつきあいくださり、ありがとうございました。次回は <a href="http://qiita.com/masao-fukase">masao-fukase</a> さんがお送りします。
ccacheでC/C++のコンパイルを高速化する

Go言語でsqlite3を扱うときにお世話になる [go-sqlite3](https://godoc.org/github.com/mattn/go-sqlite3) ですがドライバ部分がC言語で書かれています。
Linuxでは特に支障はないのですがMacでコンパイルすると何故か時間がかかってしまうので、なんとかコンパイルを高速化できないかと調べたメモです。

# ccache とは
ccache は C/C++ のコンパイル時のデータをキャッシュして2回目以降のコンパイルを高速化するツールです。

# 導入
各種パッケージマネージャーで簡単にインストールできます

## Macの場合

```bash
$ brew install ccache
```

## Debian系の場合

```bash
$ sudo apt install ccache
```

# 基本的な使い方
いつも使っているコンパイラの前に`ccache`コマンドを入れるだけ

## gccで使う

```bash
$ ccache gcc sample.c
```

## clangで使う

```bash
$ ccache clang sample.c
```

## g++で使う

```bash
$ ccache g++ sample.cpp
```

## clang++で使う

```bash
$ ccache clang++ sample.cpp
```

# Go言語のコンパイルにも使ってみる
`go build` で用いるC/C++コンパイラは環境変数`$CC`と`$CXX`で指定できます。
これを利用してGo言語のライブラリなどで使用しているC/C++のコンパイルに ccache を使ってみます。

## 呼び出し用ファイルを作る
`CC='ccache gcc'`のように指定できればいいのですが、このままだとエラーが出るので呼び出し用のファイルを作ります。

```bash
$ sudo echo '#!/bin/bash
exec ccache gcc $@' > /usr/local/bin/ccache-gcc
$ sudo chmod +x /usr/local/bin/ccache-gcc
```

## コンパイルしてみる

```bash
$ CC=ccache-gcc go build sample.go
```

## 検証

go-sqlite3 を import するだけのサンプルです

```go
package main

import (
	"fmt"

	_ "github.com/mattn/go-sqlite3"
)

func main() {
	fmt.Println("hello, world.")
}
```

キャッシュされてコンパイルが高速化するのは2回目以降なので2回目の結果を載せています。

### gcc でコンパイル (ccache なし)

```bash
$ CC=gcc time go build sample.go

real	0m42.89s
user	0m39.95s
sys 	0m2.14s
```

### clang でコンパイル (ccache なし)

```bash
$ CC=clang time go build sample.go

real	0m36.53s
user	0m32.93s
sys 	0m1.75s
```

### ccache 付き gcc でコンパイル
```bash
$ CC=ccache-gcc time go build sample.go

real	0m4.143s
user	0m2.942s
sys 	0m1.194s
```

### ccache 付き clang でコンパイル
```bash
$ CC=ccache-clang time go build sample.go

real	0m3.80s
user	0m2.10s
sys 	0m1.24s
```

# まとめ
ccache を導入して bashrc に `export CC=ccache-gcc` と書いておくと幸せになれます。
LITキャンプの謎解きイベントにおける対策(内容追加予定)

# はじめに
みなさんはじめまして！life is tech火曜スクールiphoneコースのタナハヤです。
Life is Tech ! Members Advent Calendar 2016も１３日目ですね。
今回はLife is techのキャンプにおける謎解きの対策を謎解きイベント参加回数75回以上、４５%強の脱出率を誇り、実際に謎解きを作っている筆者の秘訣を教えようと思います。
今回この記事を書くことになった経緯は「GoogleMapとMapKitの連携」という記事を書こうとしていましたが、バグが解消出来なかったため、急遽この記事を書くことになりました。そのためプログラミングと関係ないことになってしまったが、許してほしい。結構長いので、最後にまとめた箇所があるので、そこだけでも読んでくれると嬉しいです。ついでに筆者はlife is techの謎解きは全敗である。
# 謎解きイベントとは
一つの会場に集まった参加者達が協力し、様々なヒントを元に謎を解いてその場所から脱出するというもので、インターネット上における「脱出ゲーム」のリアル（現実）版である。総じて謎ときの難易度は高く、脱出率も15%から5%ほどであり、それがまた人々を熱狂に巻き込んでいる。SCRAPのリアル脱出ゲームや遊びファクトリーのリアル脱出、NAZO×NAZO劇団のリアル謎解きゲームなどがある。また大学のサークルなどが開催しているイベントもあり、今まで開催されたイベントの数は1000を超える。またリアル脱出ゲームだけでも年間のべ30万人を動員している。さらに脱出ゲームはアニメや漫画、ゲームなどとコラボしやすく、脱出ゲームというWEBのゲームがもととなっているため、わかりやすいことも知名度を上げている要員になっている。
#実際の対策について
謎解きイベントで出される謎には大きく分けて、２つのタイプの謎があり。一つを小謎、もう一つをストーリー謎と読んでいる。これは私の中での分類なので、真似してもいいが一般には通じないので注意。

小謎は謎解きイベントの序盤で大量に私達の前に出てくるドラクエでいうスライム的存在である。難易度はそれほど高くないが、数が多いのが特徴であり謎解きイベントにおいても似たような問題が出やすいので小謎をいかに速く解けるかが意外と生死の分かれ目である。小謎の中にもたまに難しいのもあり謎の解説を聞くまでわからないものもある。そういう問題が出てきたら、すぐに他のひとに回してしまうといい。小謎はストーリーと関係ない問題が隠されていることが少なくないため、人が解いた問題でも目を通しておきたい。

ストーリー謎は物語の後半に出てくることが多い。また最後の問題は必ずと言っていいほど、ストーリーに関連した問題が出る。どれだけ世界観に没入出来ているかが重要な問題もある。さらに最初のオープニングで知らされるヒントが使われるのはだいたいストーリー謎である。ほか、今まで解いた問題の法則や、形式を応用してくることが多いため、注意したい。前に解いた問題が応用されて出る問題は、背景の色や形、使う記号が前と同じでありそのことがヒントになって解けることが多い。ストーリー謎は製作者が知恵を絞って作る問題であり、小謎はそれの伏線になっていることが多い。そのため謎の難易度とオリジナリティが非常に高く、時間とひらめきが問われる問題である。
#　まとめ（結局何をすればいいのか）
今までのことをまとめると小謎は数が多く似たような問題が多い。ストーリー謎は問題数は少ないが、難易度が高い。私の経験から、ストーリー謎の対策はほぼ無理だと言っていい。ので小謎を重点的に対策するといい。
例を挙げると
・周期に関する問題は非常に多い。（月、曜日、干支など）
・同じぐらい頭文字や文字の並びに関する問題も多い。（五十音、アルファベット、色など）
・もちろんだが漢字や算数の問題も少なくなく、語彙や計算スピードを上げておくと役に立つ。
Life is techのクリスマスキャンプに関しては、2年連続で地図に関する謎が出ておりほぼ間違いなく出ると思われる。また謎解き初心者用にかんたんな問題も多いので、できるだけ速く小謎を解いて最後の方の問題に時間を回したい。
# 良問問題集（外部サイト）
[ヨクアル脱出ゲーム](http://sickssphinks.hotcom-land.com/work/yokuaru/pc/)
 [新宿に登場したSCRAPの謎200問をすべて公開](http://lirlia.hatenablog.com/entry/20150615_nazo1)
[摩天楼からの脱出練習問題](http://realdgame.jp/conan/challenge.html)
[インペルダウンへの侵入](http://realdgame.jp/zepptour3/nazo/)
wgetとcurlの使い方についてのメモ書き

# まえがき
最新記事をこちらに記載させていただきましたので、もしよろしければこちらも御覧くださいませ。
https://red-full-moon.com/wget-or-curl/

これからこういうのが増えていくと思いますが、各コマンドに関する一発メモ書き。
自分が分かればいいというスタンスなので、意味不明な書き方もあるかもしれません。
(他人に解説できないと理解できたことにならないのにね)

今回は、wgetとcurlの違いについて。
2つとも、サーバーから指定したファイルを取ってくるというイメージがあり、なにが違うのか分からないので、頭を整理します。


# wgetについて
- そもそもwgetって?
    - クローラーとしても使えるダウンローダー
    - 再帰的なダウンロードが可能
    - ファイルの種類で取ってくるものを選別できる
    - とりあえず、幅広くファイルを収集したいときに使うものっぽい

- よく見るオプション
    - -O
        - ダウンロードしたファイルの保存先。ファイル名を - とすると、ファイルに保存せずに標準出力される
        - でもぶっちゃけリダイレクトでいいと思う
    - -r
        - 再帰的なダウンロードを実行。ドメイン名のディレクトリを作成してダウンロードしたファイルを保存する
    - --http-user={username} --http-passwd={password} {host}
        - ベーシック認証がある場合に有効となる



# curlについて
- そもそもcurlって?
    - HTTP、HTTPS、FTP、FTPS、SCP、SFTP、TFTP、DICT、TELNET、LDAP、FILEとか、対応プロトコルの種類が多い
    - プロキシ、ユーザー認証、FTPアップロード、HTTP POST、SSL接続とかもできる
    - 連番のアップロードをリストを作成することなく、実行することができる
- よく見るオプション
    - -f
        - 400番台の異常系のときに、それを通知する
    - --anyauth --user user:password
        - 認証方式を自動的に判別して、突破してくれる

# 別件
[ブログ始めました、よかったら遊びに来てください](https://red-full-moon.com/)
gulp環境構築 〜ローカルサーバー〜

前回
 - pug、sass、javascriptの変更を監視して、トランスパイルをしてくれる
 - トランスパイル中にエラーが出ても停止しない

までやった。
今回は折角だし、ローカルでサーバー建ててライブロードして欲しいなってのを設定する感じ。


## ローカルサーバー

 - browser-sync
こいつがローカルサーバー建ててくれるし、そのサーバーのページを開いてるブラウザをリロードしてくれる。
んで、私はこいつを`yarn server` って打った時だけ起動してほしいから、serverタスクを作った。

```gulpfile.babel.js
// 〜 省略 〜
import blowserSync from 'browser-sync';
// 〜 省略 〜
gulp.task('server',['default'] () => {
  const serverSetting = {
    server: {
      baseDir: './dist/',
      index: 'index.html',
    },
  };
  browserSync(serverSetting);
});
```

package.jsonにyarn serverを設定する

```package.json
// 〜 省略 〜
  "scripts": {
    "start": "gulp",
    "server": "gulp server", //追加行
    "test": "gulp test"
  },
// 〜 省略 〜
```
これで`yarn server`って打てばローカルサーバー起動してくれる。
ちなみにブラウザはprimaryに設定してるやつが勝手に起動して開く。

ポート番号はデフォルト3000だけど、設定で変えられるし、他にも色々変えられる。

```例:ポート8080で起動
gulp.task('server',['default'] () => {
  const serverSetting = {
    server: {
      port: 8080,
      baseDir: './dist/',
      index: 'index.html',
    },
  };
  browserSync(serverSetting);
});
```

## ライブロード
reloadタスクを作って
watchタスクにちょっと追記してあげればおｋ

```gulpfile.babel.js
gulp.task('reload', ['main'] () =>
  browserSync.reload(),
);

gulp.task('watch', () => {
  const watchList = [
    paths.allSrcJs,
    paths.sass,
    paths.pug,
  ];
  gulp.watch(watchList, ['reload']); //この行のmainをreloadに変更
});

```

`browserSync.reload()`は現在そのサーバーに繋いでるブラウザタブを更新してくれる。
DisplacementMapを作るツールを作る

##はじめに
つい最近、Threejsで2DのDisplacementMapFilter的なものをPostProcessingで使えるよう自作した。変形用のマップ画像に何かノイズを使うのも味気ないので、手で作ったものを使えると良いなと思い、Animate(Flash)でツールをつくった。というか、昔gskinnerさんが作っていたものをほぼそのまま使った(as2からas3に書き直した）。
http://blog.gskinner.com/archives/2005/10/flash_8_gooify_.html

##作ったもの

こちらにあげた。
https://github.com/kitasenjudesign/DisplacementMapTool

こんな感じで直感的に歪ませることができるツールになっている。DisplacementMapFilterというのを使っていて、その変形の分量を定義する画像を、マウスを動かし作っている。マウスの移動量に合わせ、ブラシの方向や大きさを変えているのがミソ。
![alt](https://i.gyazo.com/6050634f42880375e73a0a745cbccb38.gif)

その画像はこんな感じ。変形の量が色で書きこまれてる。これをPNGとして吐き出せるようになっている。
![hoge.png](https://qiita-image-store.s3.amazonaws.com/0/17747/9077a870-e801-3b76-e3d0-8f569b8a646b.png)


FlashPlayerにBitmapDataをPNGに書き出すAPI（とライブラリ）があるので、それを使っている。AIR化（アプリ化）してもいいが、面倒だったのでSWFのまま。

```as3
//import com.adobe.images.PNGEncoder;　これをインポートしとく
var f:FileReference = new FileReference();
var ba:ByteArray = PNGEncoder.encode(bitmapData);
f.save(ba, "hoge.png");
```

##ThreejsのGLSL

細かい部分は割愛するが、こんな感じでさっき書き出した画像の色に従い、本来のピクセルからずらせば良い。

```glsl:fragmentShaderの一部
//さっき作った画像をテクスチャとして読み込む
vec4 col = texture2D( displacementTexture, vUv);

//本来の座標から色の分ずらす（ここではxは緑、yは青に対応）、10.0は強さ
vec2 axis = vec2(vUv.x + (col.y-0.5)*10.0, vUv.y + (col.z-0.5)*10.0);

//ほんとはvUvを使うが、ゆがめた座標axisを使い出力
gl_FragColor = texture2D( tDiffuse, axis );
```

Threejs上でもDisplacementMapできた〜。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">Displacement <a href="https://t.co/nocX87to7x">pic.twitter.com/nocX87to7x</a></p>&mdash; KitasenjuDesign (@kitasenjudesign) <a href="https://twitter.com/kitasenjudesign/status/752198100547100672">2016年7月10日</a></blockquote>

##おわりに
手軽に2Dのコンテンツやツールが作れるツールってほかにあるんだろうか？HTML5でも作れるが、かなり手間。Animateはけっこう便利。
PHYのお話

100BaseTなどのEhternetデバイスはMACとPHYが主要な部品となります。

![ETHERNETIF.png](https://qiita-image-store.s3.amazonaws.com/0/104066/d84b88ed-bca5-2d29-051f-0b58877412ed.png)

この構成は2000年くらいの100BaseTからの仕様で、10BaseTのころはMACとPHYが一体化した状態でした。

![写真（2019-08-20 13.38）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/096f7c78-703a-0a2c-0539-1b7f6fdeb91c.jpeg)
LSIのL80225というチップで2000年くらいのもの。PLCC 44Pinで結構大きいです。

![写真（2016-12-12 09.11）.jpg](https://qiita-image-store.s3.amazonaws.com/0/104066/e39290ed-771c-b76d-2f13-6587985681d1.jpeg)
IC PLUSの100MのPHY(IP101A)

![写真（2019-02-04 20.25）.jpg](https://qiita-image-store.s3.amazonaws.com/0/104066/00a9f5dd-1dac-5b1c-0559-08eed676a120.jpeg)
MARVELLの1000MのPHY(88E1116R)

PCIインターフェースのEthercatdでMACとPHYが別の部品なっていたのは、初期の一時期でMACとPHYが同一チップ内に入るようになりました。

MACからPHYへの接続はMIIと呼ばれデーターの送受信用の接続とコントロール用の接続があります。FreeBSDのethernetドライバ当初通信用とコントロール用のコードをすべてドライバに入れていましたが、NetBSDから導入したコントロール用の接続をmiibusとして扱いPHYを任意に選択できるようにしました。

1000M(1G)のものはGMIIと呼ばれ、信号線を減らしたものがRGMIIになります。SGMIIという仕様もあります。

miibusというのですが、実際はコントロール用のmdio/mdcの制御により実現されていmdbusといったほうが良かったのかもしれません。

mdioでは32個のアドレスに32個のレジスタがアクセスできます。レジスタは16ビットになります。アドレスは固定だったり、PINコンフィグレーションで設定されていたりします。

MACは接続が100Baseでも10Baseでも同じように処理していて、PHYが調整をおこないます。MACからmdioでPHYにつながれている接続があるかないかや、種類を問い合わせする事ができます。

この仕組みはFreeBSD 3.3から採用されたため、これより古いドライバでメンテナンスされていないものは、miibusが実装されていないものもあります。もし実装したとしてももはや確認できる環境がなかったりするかもしれません。

PHY用のFreeBSDのコードはsys/dev/miiにあります。

PHYの認識については、MIIでレジスタを確認する事で可能です。MIIのRegister 2と3がIDになっていてIEEEで管理された値があり、この値でPHYの種別を識別する事ができます。こに一覧が上記のディレクトリにmiidevsというファイルであります。

カーネルオプションのmiibusは全てのphyコードを入れて自動認識するためのオプションで、miiと必要なphyのオプションでもビルドする事ができます。ar531x/mipsで試したところ後者のコンフィグレーションの方が4%くらいカーネルが小さくなりました。

swtichチップにもphyが入っていて、etherswitchフレームワークではこのphy(miibus)の仕組みを再利用しています。

ar531xのネットワークインターフェースareではPHYやswitchのサポートため以下のようなオプションがあります。

|オプション|内容|
|:--|:--|
|ARE_MII|PHYが接続されているケース|
|ARE_MDIO|スイッチが接続されていてサポートがあるかukswitchで利用可能なケース|
|無し|スイッチが接続されているがサポートコードがなく、設定せずに使うケース|

i386/amd64などのPC系では、標準でより多くのデバイスをサポートしたいということで自動認識で対応したいという考えで開発されていますが、arm/mipsなどのEnbead環境でリソースが少ないケースではconfで最小限の構成にしたいとい場合もあります。

追記

areで以前はmiibusでビルドして問題なかったモジュールが、何故かクラッシュするようになりmii+rlphyでカーネルをビルドして試してみたところ問題なくなりました。謎です。。。

```
are1: <AR531x Ethernet interface> at mem 0x18200000-0x182fffff irq 2 on nexus0
miibus0: <MII bus> on are1
Trap cause = 2 (TLB miss (load or instr. fetch) - kernel mode)
[ thread pid 0 tid 100000 ]
Stopped at      0
```
IMEを使う（GTK+編）

# はじめに
GTK+はクロスプラットフォームなGUIライブラリらしいです。
その中でいかにIMEを使うかについての記事です。

# GtkIMContext
https://developer.gnome.org/gtk3/stable/GtkIMContext.html
連日のIMEの記事で何度も似たようなことを書いていますが、IME APIの役割はアプリケーションからIMEに変換や変換候補の表示のための情報を渡し、IMEからアプリケーションに挿入するべき文字列や未確定文字列の情報を渡すことです。

## 初期化など

- `gtk_im_multicontext_new`で`GtkIMContext`を取得する
- `gtk_im_context_set_use_preedit`で`TRUE`を設定する
    - 未確定文字列を自前で処理する
- 対象のウィンドウへのフォーカスに応じて適宜呼ぶ
    - `gtk_im_context_focus_in`
    - `gtk_im_context_focus_out`
- `gtk_im_context_filter_keypress`に`GdkEventKey`を渡す
- 終了時に`gtk_im_context_reset`する

## 基本実装について
以下のコールバックに登録する関数を実装します。

- `void	commit`
    - 現在の選択範囲に渡された文字列を挿入する
- `gboolean	delete-surrounding`
    - 指定範囲をキャレットからの相対位置で削除する
- `void	preedit-changed`
    - 未確定文字列を更新する
    - 未確定文字列は`gtk_im_context_get_preedit_string`で取得する
        - **注意点**
        - 取得される文字列はUTF-8
        - キャレット位置はコードポイント（あるいはUTF-32）でのインデックス
    - キャレットの位置を`gtk_im_context_set_cursor_location`でIMEに知らせる
- `void	preedit-end`
    - 未確定文字列を破棄する
- `void	preedit-start`
    - 未確定文字列の編集を開始する
- `gboolean	retrieve-surrounding`
    - `gtk_im_context_set_surrounding`で周辺の文字列とその中でのキャレット位置を返します
        - **注意点**
        - 渡す文字列はUTF-8
        - キャレット位置はUTF-8でのインデックス

## 縦書きについて
GTK+3のVersion 3.18から縦書きに対応されたようです。

- プロパティの`input-hints`に以下を設定する
    - `GTK_INPUT_HINT_VERTICAL_WRITING`

対応してるIMEはあるんですかね。
（TATEditorは一応対応していますが、私はまだ縦書きでのIMEの挙動を確認したことはありません）

# おわりに
キャレット周辺の文字列取得がアプリケーション側に委ねられているのは、動作速度的に嬉しいですね。
最低限の実装はちゃんと揃っているのですが、縦書き対応が遅かったのが……。

明日と明後日はiOS/AndroidのモバイルOSの話になります。
ons-carouselのインデックス初期化バグ対策

この記事は、[Onsen UI Advent Calendar 2016](http://qiita.com/advent-calendar/2016/onsenui) の14日目の記事として作成しました。

※このバグはOnsen UI 2.0.5以降で修正されています
※Angular2バインディングではまだ起こるようです(https://github.com/OnsenUI/OnsenUI/issues/1815)

# はじめに

「[#1565](https://github.com/OnsenUI/OnsenUI/issues/1565)は2.0.1で修正すると言ったな」
「そ、そうだ、アシアルさんっ...早く直しt...」
「あれは嘘だ」
「ウウウアァアアアア！」

以前取り上げた[ons-carouselのバグ](http://qiita.com/puku0x/items/a5072d17517023f60ba5)の改修は進んでいないようです。

しかし、アプリは作らねばならない。

# 動作環境
* OnsenUI 2.0.4 
* AngularJS 1.5.9
* Android 5.1.1
* iOS 10.1

# 問題
ons-carouselを使用する際、

- ons-carouselをスワイプしてカルーセルの現在位置を変える
- pushPage()で別のページに遷移
- 遷移後のページでAndroidならキーボード表示、iOSなら画面を横に傾ける
- popPage()で遷移前のページに戻る

と操作すると、カルーセルの位置が初期値(index=0)に戻ってしまいます。

# 解決方法

まず、`postchange`イベントが発生したらカルーセルの表示位置を保存します。
インデックス初期化バグはページ遷移後に発生するので、それ用のフラグ`pagePushed`を準備します。

```js:main.controller.js
vm.carousel.on('postchange', function(event) {
    if (pagePushed) {
        needFix = true; // バグ発生を検知
    } else {
        lastIndex = event.activeIndex;
    }
});
```

ページ遷移後、カルーセルが表示されていないにも関わらず`postchange`イベントが発火した場合は「バグが発生した」とみなします。

次にページ遷移の実行部分の処理です。

```js:main.controller.js
var options = {
    prePop: checkCarouselBug,
};
navi.pushPage('detail.html').then(function() {
    pagePushed = true;
});;
```

バグ発生時にカルーセルの位置を戻す動作を`pushPage()`の引数として渡すと、遷移先のページで呼び出すことが可能です。

```js:main.controller.js
function checkCarouselBug() {
    pagePushed = false;
    if (needFix) {
        needFix = false;
        $timeout(function() {
            vm.carousel.setActiveIndex(lastIndex); // 復元
        });
    }
}
```

最後に、遷移後のページで`popPage()`の直前にバグチェックを実行します。

```js:detail.controller.js
function back() {
    var options = {};
    args.prePop(); // バグチェック＆インデックス復元
    navi.popPage(options);
}
```

これでOK！

# おわりに

ページ毎にインデックス復元を実行しないといけなくなるので、あまり良い方法とは言えませんが、とりあえず現状はこれで対応可能です。

今回の修正の内容は以下で確認可能です。
http://codepen.io/puku0x/pen/WogwRg

※ 遷移後ページの戻るボタンの表示が崩れていますがv2.0.4の不具合のようです
待ち時間をD言語くんで彩る - 進捗表示ライブラリを作った

かのマハトマ・ガンジーも
> [もし、私にD言語くんがなければ、これほど長く苦しい戦いには耐えられなかったでしょう。](http://meigennote.com/?p=134#i-11)

と言ったように、生活の中でD言語くんを忘れないようにすることはとても大切です。退屈な待ち時間でもそこにD言語くんがいれば幸せになれるのではないでしょうか。
そこでPythonの[progress](https://github.com/verigak/progress)を参考にライブラリ[progress](https://github.com/kotet/progress)を作りました。[dubに登録してあります](http://code.dlang.org/packages/progress)。

## つかいかた

```d:九九を教えてくれるD言語くん
import progress.dman;
import core.thread : Thread,dur;
import std.string : format;

void main()
{
    auto dman = new DmanSpinner;
    foreach(i;0 .. 9*9)
    {
        dman.message =
        {
            auto left = (i/9)+1;
            auto right = (i%9)+1;
            return "%s * %s = %s".format(left,right,left*right);
        };
        dman.next();
        Thread.sleep(dur!("msecs")(500));
    }
    dman.finish();
}
```

![optimized.gif](https://qiita-image-store.s3.amazonaws.com/0/57768/074d96f2-4e9b-f255-47eb-7d2f625b5a43.gif)

これであなたのプログラムにもD言語くん要素を入れることができます!

---

それではよいD言語くんライフを!

![optimized.gif](https://qiita-image-store.s3.amazonaws.com/0/57768/27668060-85d5-2769-7953-d396db3551b7.gif)
Riot.jsでSVGを描画しようとしたら小一時間程ハマった話

この記事は[Riot.js Advent Calendar 2016](http://qiita.com/advent-calendar/2016/riotjs)の14日目の記事です。
[昨日に続いて](http://qiita.com/nayuneko/items/25b7cb174478aed8b482)記事を書かせていただきます！

先日Riot.jsでSVG画像を生成するコードを書いていたのですが、その時ハマった時のお話です。

以下のコードを実行するとこのような画像が描画されます。
![cross.png](https://qiita-image-store.s3.amazonaws.com/0/73378/d59209c5-03a9-62ff-3383-a024295b8f8f.png)

```html:svg.html
<svg-cross></svg-cross>
<script src="https://cdnjs.cloudflare.com/ajax/libs/riot/2.6.7/riot+compiler.js"></script>
<script type="riot/tag">
<svg-cross>
<svg width="100" height="100" version="1.1" viewbox="0 0 100 100">
  <line x1="0" y1="50.5" x2="100" y2="50.5" stroke="gray"/>
  <line x1="50.5" y1="0" x2="50.5" y2="100" stroke="gray"/>
  <line each={l in lines} x1={l.x1} y1={l.y1} x2={l.x2} y2={l.y2} stroke={l.color} stroke-dasharray="2,2"/>
</svg>
this.lines = [
  {
    x1: 10.5,
    y1: 10.5,
    x2: 90.5,
    y2: 90.5,
    color: 'red',
  },
  {
    x1: 90.5,
    y1: 10.5,
    x2: 10.5,
    y2: 90.5,
    color: 'blue',
  },
];
</svg-cross>
</script>
<script>
  riot.mount('svg-cross');
</script>
```

見た目上はまったく問題ないんですがコンソールログを見たら大量のエラーが…

```txt:コンソールログ(一部抜粋)
riot+compiler.js:1994 Error: <line> attribute x1: Expected length, "{l.x1}".
  setInnerHTML @ riot+compiler.js:1994
  _mkdom @ riot+compiler.js:996
  Tag @ riot+compiler.js:1497
  mountTo @ riot+compiler.js:2454
  pushTags @ riot+compiler.js:2597
  each @ riot+compiler.js:1959
  pushTags @ riot+compiler.js:2601
  riot.mount @ riot+compiler.js:2652
  (anonymous) @ riot+compiler.js:3537
  done @ riot+compiler.js:3453
  compileTag @ riot+compiler.js:3460
  compileScripts @ riot+compiler.js:3471
  (anonymous) @ riot+compiler.js:3524
  riot.mount @ riot+compiler.js:3537
  (anonymous) @ svg.html:36
riot+compiler.js:1994 Error: <line> attribute y1: Expected length, "{l.y1}".
  setInnerHTML @ riot+compiler.js:1994
  _mkdom @ riot+compiler.js:996
  Tag @ riot+compiler.js:1497
  mountTo @ riot+compiler.js:2454
  pushTags @ riot+compiler.js:2597
  each @ riot+compiler.js:1959
  pushTags @ riot+compiler.js:2601
  riot.mount @ riot+compiler.js:2652
  (anonymous) @ riot+compiler.js:3537
  done @ riot+compiler.js:3453
  compileTag @ riot+compiler.js:3460
  compileScripts @ riot+compiler.js:3471
  (anonymous) @ riot+compiler.js:3524
  riot.mount @ riot+compiler.js:3537
  (anonymous) @ svg.html:36
  riot+compiler.js:1994 
...
```

lineの座標指定属性に設定したテンプレート変数用の`{}`がうまくパースできなくて怒られているみたい？(マジックナンバーでは問題なし)
別に表示上は問題ないのですが、コンソールログが出続けるのは気持ち悪い！(SPAにした日にはガンガンコンソールログが蓄積されていきますしね。。)

いろいろ調べていたら解決策っぽいのが…？
[SVG tries to render before RiotJS replaces variables](https://github.com/riot/riot/issues/853)
明確な原因までは書かれていませんでしたが、x1,x2,y1,y2の属性名にそれぞれ`riot-`を付けてあげればいいみたいですね。

```diff
-  <line each={l in lines} x1={l.x1} y1={l.y1} x2={l.x2} y2={l.y2} stroke={l.color}/>
+  <line each={l in lines} riot-x1={l.x1} riot-y1={l.y1} riot-x2={l.x2} riot-y2={l.y2} stroke={l.color}/>
```

ちなみに`<line>`以外ですと、`<text>`のx,yでも発生しました。

はー、すっきりした。。。
しかしRiot.jsでSVGを扱えるのはありがたいですね。図やグラフもサクサク描けそうです。
Sinatra用にTemplateを用意して開発の初期コストを低減する

この記事は、[SLP_KBITその２ Advent Calendar 2016](http://qiita.com/advent-calendar/2016/slp_kbit2)の14日目の記事です。

# はじめに

Railsでアプリ開発を行う際に、テスト用の設定ファイルやTwitterbootstrapを使うために色々と書いたり、他のアプリからコードをコピペしたり、実際にコードを書き始めるまでの準備にとても時間がかかる場合があると思います。
その手間を軽減するために、Railsには[Application Template](http://railsguides.jp/rails_application_templates.html)という機能があります。
しかし、Sinatraには、自分が調べた限りでは、このような機能はありませんでした。
そのため、Sinatraを軽量なRailsのように扱いたいと思っていました。

# Sinatraのメリット

Ruby使いがWebアプリを作る、となるとRailsが一番に思い浮かぶと思います。
しかし、数時間規模のハッカソンやデモ用のアプリ開発などでは、Railsは大げさでちょっと……という方もいらっしゃるのではないでしょうか。
個人的には、**モデルが存在しない** or **静的なモデルしか存在しない**場合にはRailsよりもSinatraを使ったほうがスリムなアプリ開発が行えるのではないかと考えています。

# SinatraTemplateとは

主な機能としては、テストやアセットまわりの、アプリ開発する上で必須の設定をあらかじめ用意したものになります。
RailsのApplication TemplateのSinatra版のようなものを目指しています。
ソースコードはこちら (https://github.com/gembaf/sinatra_template) にあります。

ディレクトリ名などは、Railsを参考にしています。
まずは、ざっくりと使い方を説明したいと思います。

# 使い方

流れとしては、以下のようになります。

- SinatraTemplateをcloneする
- 自身のリポジトリとして名前やremoteなどを変更する
- 自身のリポジトリとしてpushする

clone後のリポジトリの初期化用として、`init.sh`を用意しています。
実行すると以下のような処理が行われます。

- ユーザ名とリポジトリ名の入力を求める
- 上記の情報を基に、SinatraTemplateのコード上に存在するユーザ名とリポジトリ名を書き換える
- SinatraTemplateのgitの履歴を消す(`rm -rf .git`)
- 自分自身(`init.sh`)を削除する

このスクリプトの実行後には、gitの管理下にないSinatraTemplateが残ることになります。
その後は、自分のリポジトリとして扱えば、色々と用意の整った状態で`first commit`できます。

# テストまわり

テスト関係は、`rspec`と`factory_girl`というRailsでもメジャーな組み合わせを導入しています。
さらに、`capybara`と`poltergeist`も導入しているので、UIのテストも可能です。
また、コードの品質評価として、`rubocop`も導入しています。

# アセットまわり

JavaScript関係のライブラリの管理は`bower`を利用しています。
デフォルトで使用しているライブラリは、`jquery`、`bootstrap`、`bootswatch`です。
アセットまわりの記法としては、`coffee`と`sass`をデフォルトとしています。

もちろん、変更の度にコンパイルをする必要はなく、Railsと同じような感じで使うことができます。

# Model

初めの方で述べた通り、モデルとして扱うデータは、静的なデータを想定しています。
動的なデータをDBで扱うようなものは、Railsを使うべきだと思います。
ユニットテストの例も兼ねて、UserAgentの判別を行うモジュールのみ、あらかじめ用意してあります。

# View

Railsと同じように、layoutファイルを用意しているので、全体的な見た目を統一することができます。
デフォルトで、ナビゲーションバーを表示するようにしています。

# herokuへのデプロイ

herokuへデプロイするための設定も整えているので、以下の流れでデプロイできます。

```bash
$ heroku create
$ heroku config:set BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-multi.git
$ git push heroku master
```

# 外部サービス

`circleci`と`codeclimate`に必要な設定ファイルを用意しているので、自分のリポジトリとして各サービスで設定するとそのまま使えます。

# おわりに

SinatraTemplateは、自分用として作っているので、まだまだ作りが甘い部分が多々あります。
今後は、ユーザが必要な機能やライブラリを選択して、それ以外のものについては、初期化の段階で削除できるような機能をつけたいと思っています。
あと、今回は生のSinatraを触ったことで、Railsのスゴさを改めて感じることができました。