OmniAICreator/Qiita-1.07M huggingface dataset:
Ruboty | 1行の区切り文字列を出力する ruboty-hr を作成しました #ruboty

# 1行の区切り文字列を出力する ruboty-hr を作成しました

## <i class="fa fa-cubes" style="font-size:1em;"></i> 概要
1行の区切り文字列を出力する ruboty-hr を作成しました

## <i class="fa fa-cube" style="font-size:1em;"></i> 用途
チャットツールの見た目上、明確に話題を区切りたい時に
ただの文字が続いていると、ぱっと見で分かりにくいものです。

そこで、特定の文字や記号や絵文字を一行分並べることで、
html の hr のような区切り線を作成して話題の切れ目を分かりやすくします。

区切り文字は自由に設定可能にします。

## <i class="fa fa-cube" style="font-size:1em;"></i> Installation

Add this line to your application's Gemfile:

```ruby
gem 'ruboty-hr'
```

And then execute:

    $ bundle

## <i class="fa fa-terminal" style="font-size:1em;"></i> Commands

|Command|Pattern|Description|
|:--|:--|:--|
|hr|/hr\s+(?&lt;text&gt;.+?)\s\*(?&lt;count&gt\d*)\z/|Display single line punctuation characters (default 80 times)|

## <i class="fa fa-file-text-o" style="font-size:1em;"></i> Usage
### hr
* Display single line punctuation characters (default 80 times)

~~~
>ruboty hr @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
>ruboty hr - 40
----------------------------------------
>ruboty hr ~= 40
~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
~~~

## <i class="fa fa-gears" style="font-size:1em;"></i> ENV

|Name|Description|
|:--|:--|
|--|--|

## <i class="fa fa-puzzle-piece" style="font-size:1em;"></i> Dependency

|Name|Description|
|:--|:--|
|--|--|

## <i class="fa fa-arrow-circle-right" style="font-size:1em;"></i> 参照
* <i class="fa fa-external-link" style="font-size:1em;"></i> [ruboty-hr GitHub](https://github.com/tbpgr/ruboty-hr)
* <i class="fa fa-external-link" style="font-size:1em;"></i> [ruboty-hr RubyGems](http://rubygems.org/gems/ruboty-hr)
setup mac yosemite

## change mac setting
- mission control - hotkey screenlock
- (security - firewall)
- security - require password
- energy - sleep time, display off time
- keyboard - fnkey, Capslock to control
- trackpad - tap click, right click, scroll natural
- user - off the guest
- accessibility - zoom
- dock setting - auto hide, layout 
- sound - show in menu bar
- general - change menubar and Dock color


## xcode
- install xcode - appstore

- xcode command line tools install

```shell-session
$ xcode-select --install
```

## ansible

https://devopsu.com/guides/ansible-mac-osx.html

```shell-session
$ sudo easy_install pip
$ sudo pip install ansible --quiet
```


## install Homebrew
http://brew.sh/index_ja.html

```shell-session
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

$ brew doctor
$ brew install caskroom/cask/brew-cask
```


## enable locate

```shell-session
$ sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist
```
mrubyとCRubyの非互換とその対応方法

（メモ。詳しくはあとで追記するかも。）

# `"foo" "bar"` の文字列連結ができない

`"foo" + "bar"` を使う。

# `defined?(Foo)`がエラーになる

`const_defined?(:Foo)`を使う。

mrubyに`defined?(Foo)`が実装されていない理由は、`Foo`が未定義でもエラーにさせないために特殊な実行が行われており、それを嫌ったためだったはず。

# `:"foo#{a}bar#{b}"`形式のSymbol定義がエラーになる

`"foo#{a}bar#{b}".to_sym`を使う。

# `$:`等の変数がない

`$LOAD_PATH`等はあったりするのでこちらを使う。

# RUBY_PATCHLEVEL等の定数がない

適当に定義して回避する？

なお、2016年現在のmrubyにはパッチレベルの概念がない。github:mruby/mrubyのmasterとmruby forumのリリース版のみ。

# RbConfigがない

同上。

なお、mrubyはクロス開発もごく自然に行われるため、ビルド時のOSの情報とかは役に立たないことがあるのに注意。

# `IO`がない

github:iij/mruby-ioを使う。

# `Dir`がない

github:iij/mruby-dirを使う。

Dir.glob は github:gromnitsky/mruby-dir-glob を使う。

# `tmpdir`がない

github:iij/mruby-tempfileを使う。

# `require`がない

github:iij/mruby-requireを使う。

# `ENV`がない

github:iij/mruby-envを使う。

# `Regexp`がない

github:iij/mruby-regexp-pcreやgithub:mattn/mruby-onig-regexpを使う。

# `Iconv`がない

github:mattn/mruby-iconvを使う。

# fileutils.rb、pp.rb等がない

fileutilsに関してはgithub:gromnitsky/mruby-fileutils-simple があったりする（実装は力技ですごい）のでこの辺を使ったりする。

pp.rbの代わりは書いた -> https://github.com/takahashim/mruby-pp

https://github.com/kou/mruby-pp　もある。

# `Kernel#exec`がない

`Kernel#system`ならgithub:iij/mruby-processにあったりするのでこちらでもよければこれを使う。

あと、github:haconiwa/mruby-execがある（動作未確認）。

# `at_exit`がない

github:ksss/mruby-at_exit を使う。

mruby本家にat_exitがない理由については　http://ksss9.hatenablog.com/entry/2016/08/19/224631 を参照。そもそもインタプリタの実行終了とプロセスの終了が一致するCRubyと、インタプリタが終了してもプロセスが終了するとは限らないmrubyでat_exitをどう揃えるべきか、という問題がある。なお、ISO Rubyではat_exitは定義されていない。

# `File.executable?`がない

github:iij/mruby-io にあるかと思ったらなかった。自力でなんとかすべきか。

executable?はOSに依存する概念なのでいろいろめんどくさい、という難点がある。

# その他いろいろ動かないものがある

（自力で直せそうなら修正してpull requestをする→一部した）
PythonでQuandlからデータを取得する

株価の取得方法について調べていて見つけた[Quandl](https://www.quandl.com/)というサービスが良さげだったので使ってみた。

# Quandl

Quandlは金融、経済などの数値データの検索エンジンで、さまざまなソースから得られたデータを検索し、グラフや表を表示させることができる。またデータはJSON、CSVなどの形式でダウンロードしたり、[Plotly](https://plot.ly/)などのサービスに取り込ませることもできる。

[Getting Started](https://www.quandl.com/help/welcome)

一部有料のデータもあるが多くのデータについては無料で取得することができる。

様々な言語のライブラリも用意されており(https://www.quandl.com/help/libraries )、APIを用いてデータの取得や検索ができるようになっている。

各データを個別に提供しているだけではなく、データをまとめているページがある。
画面左上からData > Data Browser とクリックすると国やデータの種類でまとめられている中から探すことができる。
例えば、以下のようなページがある。

* 日本の人口
    * https://www.quandl.com/c/japan/japan-population-data
* アップルについての数字
    * https://www.quandl.com/c/stocks/aapl 
* 国別の平均余命
    * https://www.quandl.com/c/demography/life-expectancy-at-birth-total-by-country
* インターネット普及率
    * https://www.quandl.com/c/society/internet-users-by-country  
 
# Pythonライブラリのインストール

Quandlのライブラリはpipを使ってインストールすることができる。(Numpyとpandasが必要)

```bash
$ pip install Quandl
```

# Pythonライブラリの使い方

Quandlモジュールをインポートし、get関数にQuandl Codeを渡すと、pandasのDataFrameとしてデータを取得することができる。Quandl Codeはデータを検索すると画面の右上の方に表示されている。

```pycon
>>> import Quandl
>>> df = Quandl.get('GOOG/NASDAQ_GOOG')
>>> df[:5]
             Open   High    Low  Close  Volume
Date                                          
2004-08-19  49.96  51.98  47.93  50.12     NaN
2004-08-20  50.69  54.49  50.20  54.10     NaN
2004-08-23  55.32  56.68  54.47  54.65     NaN
2004-08-24  55.56  55.74  51.73  52.38     NaN
2004-08-25  52.43  53.95  51.89  52.95     NaN

[5 rows x 5 columns]
```

## トークンの使用

Quandlのアカウントがない場合にはAPIの使用回数は1日に50回までに制限されている。
Quandlにアカウント登録しアカウントページに表示されているトークンを一緒に渡せばAPIを無制限に使うことができる。

```pycon
>>> df = Quandl.get('GOOG/NASDAQ_GOOG', authtoken='YOUR_AUTH_TOKEN')
```

## 複数のデータの同時取得

以下の例のようにQuandl Codeのリストを引数として渡すことで同時に複数のデータを取得することができる。
データ間の比較をしたいときなどには便利。

```pycon
>>> df = Quandl.get(["WORLDBANK/JPN_IT_NET_USER_P2",
...                  "WORLDBANK/KOR_IT_NET_USER_P2",
...                  "WORLDBANK/CHN_IT_NET_USER_P2"])
>>> df.columns = ["Japan", "Korea", "China"]
>>> df[:5]
               Japan     Korea     China
Date                                    
1990-12-31  0.020294  0.023265  0.000000
1991-12-31  0.040438  0.046124       NaN
1992-12-31  0.096678  0.098404       NaN
1993-12-31  0.401278  0.249947  0.000169
1994-12-31  0.799684  0.311359  0.001168
```

## データの検索

search関数を使ってデータを検索することができる。verboseはデフォルトではTrueになっており、Trueの場合上位4件のデータを標準出力へ出力する。

```py
>>> dataset = Quandl.search("Internet User", source="WORLDBANK", verbose=False)
```

結果の数が多い場合にはページが分割されているので、ページ数を指定して繰り返し実行する必要がある。ページ数が多すぎるとスロットリングに引っかかることがあるので注意。

```py
>>> page = 0
>>> dataset = []
>>> import itertools as it
>>> for page in it.count():
...     d = Quandl.search("Internet User", page=page, source="WORLDBANK", verbose=False)
...     if not d:
...         break
...     dataset.extend(d)
```

基本的にはブラウザで検索するのと同じだが、Quandl Codeをまとめて取得したいときなどはAPIを使うと楽かもしれない。

## その他

その他のAPIの詳細についてはドキュメントを参照。

PythonライブラリではサポートされていないオプションなどについてはAPIのドキュメントを参照。urllib2などを使って直接URLを開くことで使うこともできる。

# 参考

* https://www.quandl.com/help/api
* https://www.quandl.com/help/python
関数合成を短く

```scala
implicit class RichFunction1[A, B](val f: A => B) extends AnyVal {
  def |>[C](g: B => C) = f andThen g
  def <|[C](g: C => A) = f compose g
}

val plus = (_: Int) + 1
val minus = (_: Int) - 1
val suffix = (_: Int) + "!"

val f = plus |> minus |> suffix
println(f(1))
println(f(2))

val g = suffix <| minus <| plus
println(g(1))
println(g(2))
```

記号これじゃないほうがいいな
RubyでとりあえずサクッとID的なものを作成する

# ID的なもの

完全ではなくともとにかくIDとなるものが欲しいことはよくありますね。
というわけで、こういう条件で方法を探ってみました。

- 作成された順番は分からなくていい
- 処理が軽いといい(カリッカリにチューンするほどではないが)
- 形式はそんなにこだわらない

# 時間測定

ものすごい適当に3つの方法を選んで、10000回実行した時の時間を測ってみました。

## SecureRandom.uuid

こんな感じの文字列が取れます
`6782f08f-534a-44f2-bce5-1b65d2fe340b`

```rb
Benchmark.measure do
  10000.times{ SecureRandom.uuid }
end
=> #<Benchmark::Tms:0x007fe2349f4db8
 @cstime=0.0,
 @cutime=0.0,
 @label="",
 @real=0.074855,
 @stime=0.0,
 @total=0.07000000000000028,
 @utime=0.07000000000000028>
```

## Digest::SHA1.hexdigest

こんな感じのIDが取れます
`09b4f44552a6c7a879bbe59fde09b4c523c687cd`

```rb
Benchmark.measure do
  10000.times{ Digest::SHA1.hexdigest([Time.now, rand].join) }
end
=> #<Benchmark::Tms:0x007fe23fab2fb0
 @cstime=0.0,
 @cutime=0.0,
 @label="",
 @real=0.08288,
 @stime=0.0,
 @total=0.08000000000000007,
 @utime=0.08000000000000007>
```

## Identifier.generate

[identifier](https://github.com/ksylvest/identifier)というgemがあったので試してみました。

こんな感じのIDが取れます
`00de7f79-b6c4-4507-8614-242a7bef930f`

```rb
Benchmark.measure do
  10000.times{Identifier.generate}
end
=> #<Benchmark::Tms:0x007fe23d9e1e30
 @cstime=0.0,
 @cutime=0.0,
 @label="",
 @real=0.098369,
 @stime=0.009999999999999787,
 @total=0.10999999999999943,
 @utime=0.09999999999999964>
```

# 結果など

軽さは10000回でこのくらいならまあどれでもいいかな。
今回の目的からすると新たにgem入れることもないし、`SecureRandom.uuid`が楽なのでそれでいいかな。

調べてたら`SecureRandom.uuid`は中で`SecureRandom.random_bytes`叩いてるのを見てなるほどーってなったりしてました。
Dovecot で Sieve scripts を LDAP から読み込む

dovecot を sieve に対応させるための [Pigeonhole](http://pigeonhole.dovecot.org/index.html) で Sieve scripts を LDAP から読み込む機能が昨年の10月末に追加されたので試してみた。

```lang:release_note抜粋
+ Implemented storage driver for retrieving Sieve scripts from LDAP.
  This currently cannot be used with ManageSieve.
NaN.
```

###前提条件
- dovecot 2.2.15 が /usr/local/dovecot 以下にインストールされている
- dovecotの設定ファイルは /etc/dovecot 以下から読み込む
- メールの配送プロトコルに LMTP を使用している

####1. pigeonholeのインストール
- - -
pigeonholeのインストール

```install
$ tar xzf dovecot-2.2-pigeonhole-0.4.6.tar.gz && cd dovecot-2.2-pigeonhole-0.4.6
$ ./configure --prefix=/usr/local/dovecot --with-dovecot=/usr/local/dovecot/lib/dovecot -with-ldap=plugin
$ make
$ su
# make install
```

####2. Sieve script を ldap に追加
- - -
下記は、メールヘッダーの**From**に **hogehoge@** が含まれていた場合、**hogehoge**というMailBOXに保存するという sieve script を書いたldifファイル

```lang:sieve_rule.ldif
dn: uid=test,ou=People,dc=test,dc=com
changetype: modify
replace: storeSieveScript
storeSieveScript: require "fileinto";
 if address :contains "From" "hogehoge@" {
 	fileinto "hogehoge";
 	stop;
 }
```

**LDAPに設定反映**

```ldapmodify
# ldapmodify -x -W -D "cn=admin,dc=test,dc=com" -f sieve_rule.ldif 
Enter LDAP Password: 
modifying entry "uid=test,ou=People,dc=test,dc=com"
```

**LDAPの確認**

```ldapsearch
# ldapsearch -x -b "dc=test,dc=com" mailroutingaddress=test@test.com storeSieveScript
dn: uid=test,ou=People,dc=test,dc=com
storeSieveScript:: cmVxdWlyZSAiZmlsZWludG8iO2lmIGFkZHJlc3MgOmNvbnRhaW5zICJGcm9
 tIiAiaG9nZWhvZ2VAIiB7CWZpbGVpbnRvICJob2dlaG9nZSI7CXN0b3A7fQ==
```

sieve scriptルールはMIMEエンコードされて保存される
####3. dovecot に ldap に保存された sieve ルールを読み込む設定を追加
- - -
ldapから読み込むルールを追加

```/etc/dovecot/conf.d/90-sieve.conf
plugin {
  sieve = ldap:/etc/dovecot/sieve-ldap.conf.ext
  sieve_plugins = sieve_storage_ldap
}
```

sieveルールをldapsearchする為の設定ファイル

```/etc/dovecot/sieve-ldap.conf.ext
hosts = 127.0.0.1
base = dc=%Dd
sieve_ldap_script_attr = storeSieveScript
sieve_ldap_filter = (mailRoutingAddress=%u)
```

dovecotの再起動
`# systemctl restart dovecot`

####4. 配送テスト
- - -

telnetでテストメール配送

```sendmail
# telnet 127.0.0.1 2003
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
220 test.com Dovecot ready.
LHLO localhost
250-test.com
250-8BITMIME
250-ENHANCEDSTATUSCODES
250 PIPELINING
mail from:<test@test.com>
250 2.1.0 OK
rcpt to:<test@test.com>
250 2.1.5 OK
data
354 OK
Subject: sieve test mail
From: hogehoge@test.com
To: test@test.com
Message-ID: <123@test.com>

This is test mail.
.
250 2.0.0 <test@test.com> UVn7HvA6qVTbRAAAo+CWOA Saved
quit
221 2.0.0 OK
Connection closed by foreign host.
```

ログから **INBOX** ではなく **hogehoge** に配送されたことを確認

```maillog
Jan  4 22:12:58 test1 dovecot: lmtp(test@test.com): UVn7HvA6qVTbRAAAo+CWOA: sieve: msgid=<123@test.com>: stored mail into mailbox 'hogehoge'
```

配送先の **hogehoge** メールボックスはメール配送前に作成しておく必要がある。
React.jsはMVCのVじゃない。フレームワークだ。

## 問題提起

[Why React?](http://facebook.github.io/react/docs/why-react.html)

> Many people choose to think of React as the V in MVC.

で語られている通り、一般的にはいわゆるViewの部分（仮想DOM）だけを担うライブラリと思われているようです。
「仮想DOMは描画が速いんだ」などと言う人が多くいますが、React.jsによるDOM操作の効率化（差分反映の仕組み）で劇的に改善されるケースってそこまで多くないんじゃないかと思っています。

「じゃぁ、Reactって学習コストに合わなくね？」と僕は思っていましたが、このスライド（[React JS and why it's awesome](http://www.slideshare.net/AndrewHull/react-js-and-why-its-awesome)）を見て、実際に学習してみて納得しました。

**これはクライアントサイドの設計をひっくり返すフレームワークだと。**


## 何がいいのか？

Reactは以下の機能を持っています。（ざっくり過ぎて意味不明かもしれませんが、機能説明の記事ではないので略します。詳しくは公式サイトで。）

- 片方向データバインディング機構
- （即時）差分レンダリング
- jsxを使った仮想DOMの宣言
- 上位コンポーネントからのデータ（props）はimmutable

これらを使うとどう便利になるかを見ていきます。

### HTMLを書く必要がない。

jsxという書式による仮想DOMによって、実質的にHTMLを書く必要がなくなります。

元々HTMLは静的なページを作るためのものだったせいか、近年のWebアプリケーションには時代遅れになっています。
Angularやvue.jsなどではHTMLを独自に拡張していますし、jQuery PluginではSelecterだけ喰わせれば後はライブラリがよろしくやってくれるものが多いです。
PolymerとかElm、Senchaなどに関しては生HTMLをほぼ書かないようになっているので、これは時代の流れなんだろうなと。

### コンポーネントを作るだけでいい。

> Everything is Component!

MVCなんて要りません。そのコンポーネントがどんな状態を持っていて、どんな振る舞いをすべきかを記述するだけでいいのです。

ボタンや入力フォームはもちろん、ページ全体も一つのコンポーネントとして考えます。

### コンポーネントの挙動を宣言的に扱える。

事前にコンポーネントを宣言しておけば、後で生成してあげるだけで適切な挙動をしてくれます。生成後にフローを作る必要はありません。もちろん、DOMの再描画も、必要なときに最適な形でやってくれるので楽です。（俗に言うFRPです。）

これが仮想DOMを使っていない場合は、リアルDOMにmountした後からその対象へのイベント追加などをしてあげなければいけなくて、とても不安定です。

### idを指定しなくてもよろしくやってくれる。

個人的な意見なので賛同してもらえるかわかりませんが。。
僕が我流フレームワークを作っていた時も、Polymerなどを参考にして全てをコンポーネント化しようとしていましたが、どのDOMにmountするのかを決めるためにid属性を使おうとすると、idの衝突が起きてしまうケースがあります。（そしてデバッグが厄介です。）

Reactでは、idなど使わなくても親コンポーネントが子コンポーネントを必ず知っているため、一意なidを〜とか考えなくてもいいのです。

### データフローが統一される。

Reactでは、子コンポーネントは親コンポーネントから渡されたデータは変更できません。

これによって、各コンポーネントが持つデータ（状態）は、自分しか変更できないため、他のコンポーネントの挙動を考慮する必要がなくなりシンプルな設計になります。

### イベントのフローも統一される。

コンポーネント化していく場合には当たり前ですが、子は親のことを知りません。
事前に定義しているインターフェース（this.props）が受け取る値だけを扱えばよいのです。

子がイベントを発火したとき、そのイベントを子だけで処理できない場合は親へ投げられます。（HTMLでもバブリングという仕組みがありますね。）

親に子のデータを渡したい場合はこのイベントの引数として渡してあげます。

（これらの統一されたフローのことをFluxと呼んでいるようです。
　公式サイトの図は複雑でよくわかりませんが。。。）

### 純粋なモデルを扱える。

片方向のデータバインドなので、

- prop/stateの変更を常に反映できる。
- DOMの状態は考慮しないのでモデルは汚されない。

といいとこ取りできます。
（その代わり、単純なサンプルではAngularとかより記述量が増えます。）

### 単体テストがしやすい

各コンポーネントで閉じている、仮想DOMの状態をReactが管理している、ので原理的にはテストがやりやすいはずです。

が、まだ未検証です。

## 懸念点

### クロスブラウザ対応

たぶんそこらへんはよろしくやってくれてるんだろうと思いますが、特にスマホでちゃんと使えるかとかはよく知りません。

### webpack/browserify必須？

コンポーネントを完全に独立させるにはcommonJSスタイルで書く必要があります。

これらをサポートしているモジュール管理ツールが必要です。

### テスト/デバッグ

一応ツール群が用意されているものの未検証です。

実行時デバッグは、ほぼJSなので問題なさそうです。

### React Componentsがまだまだ不十分

数も多くないし、Demoを載せてくれてるのがあまりない。

個人的には、しばらくはjQuery pluginに頼ることになるかなと思ってます。
（jQuery Pluginへの対応については、`componentDidMount`をうまく使うことでなんとかなります。データ変更の親への反映は当然イベントを発火させます。）

[サンプルコード](https://github.com/uryyyyyyy/reactSamples/tree/master/with_jquery)
3dsMAX2012布地モディファイヤ応用

![MAX.JPG](https://qiita-image-store.s3.amazonaws.com/0/64856/f4ffb8f4-b9bd-7111-d625-8ac2c05621c6.jpeg)
シミュレーションをかけた後に
どうしても起きてしまうめり込み等の修正をする為のやり方

例

プレーンを作成
↓
参照オブジェクト作成
↓
スプラインサークルを作成
↓
スプラインの編集
モディファイヤ
選択スプライン→分解
選択セグメント→スプライン曲線全選択→分割２くらい
選択頂点→スプライン曲線全選択→連結
↓
「オリジナル」の頂点を選んでから
「参照オブジェクト」のスキンエンベロープのスキンを選択
↓
ウェイトを調整する。

因みに画像はスキンをかけた時のレジストリエラー対処方法
PlayFramework インターセプト

# リクエストのインターセプト
GolobalSettignsを継承したクラスを使用し、アプリケーション起動時や終了時に処理をいれることができます。
今回はリクエスト時に処理をフックする方法をご紹介します。

## サンプル
global.scalaファイルを作成し、下記のように記述します。

```lang:sample
import play.api._
import play.api.mvc._
import play.api.mvc.Results._
 
object Global extends GlobalSettings {
 
  override def onRouteRequest(request: RequestHeader): Option[Handler] = {
     println("リクエストの確認:")
     println("executed before every request:" + request.toString)
     super.onRouteRequest(request)
  }
}
```
onRouteRequestをオーバーライドすることで、リクエストをフックすることができます。
material uiをRailsで使ってみた


[material ui](http://callemall.github.io/material-ui/)は[react.js](http://facebook.github.io/react/)を使ってMaterial Designを実現しています。

material uiはbrowserifyと一緒に使うことになります。
そこでbrowserify-railsを利用してみました。

この方法だとJavaScriptを変更する度にbrowserifyが実行されてとても重いです。

また、railsプロジェクト内に埋め込みする利点も浮かびません。

そのため、この手法はおすすめしませんが、せっかく試したので記録を残しておきます。

作成したソースコードは[eiel/material-ui-rails-sample](https://github.com/eiel/material-ui-rails-sample)に置いています。

# 利用方法

利用するには、rubyとnodejsがインストールされている状態で

```
$ bundle install
$ npm install
$ bin/rails s
```

になります。

# 作業内容

## プロジェクトの作成


```
$ rails new --no-rc material_ui
$ cd material_ui
```

`--no-rc`はなくても構いませんが一応。

## 利用するgem

```Gemfile
gem 'browserify-rails', '~> 0.5'
gem 'less-rails'
gem 'therubyracer', platforms: :ruby
```

browserify-railsを使うとnpmのモジュールを使えるようになります。
また、material-uiのCSSがlessで書かれているので、less-railsとtherubyracerを入れています。

## 利用するnodeモジュール

package.jsを用意します。

```package.json
{
  "name": "something",
  "devDependencies" : {
    "browserify": "~> 6.3"
  },
  "license": "MIT",
  "engines": {
    "node": ">= 0.10"
  }
}
```

用意したら`npm install`します。

```
$ npm install
```

利用するnode packageをインストールします。

```
$ npm install --save material-ui react
$ npm install --save-dev reactify
```

## 設定

JSXを変換するのにreactifyを使うので、オプションを設定しています。
また、material-uiに付属しているlessファイルの置き場にlessのパスを設定します。

```config/application.rb
module MaterialUi
  class Application < Rails::Application
    # ... 中略 ...
    config.browserify_rails.commandline_options = ["-t reactify"]
    config.less.paths << "#{Rails.root}/node_modules/material-ui/src/less/"
  end
end
```

## 表示するページの作成

`home#index`を用意して、そこで遊ぶことにしました。

```
$ bin/rails g controller home index
```

ルートを`home#index`に設定します。

```config/routes.rb
Rails.application.routes.draw do
  root 'home#index'
end
```

material_uiに付属のRaisedButtonを使ってみます。

```app/assets/javascripts/material_ui.js
var React = require('react'),
  mui = require('material-ui'),
  RaisedButton = mui.RaisedButton;

$(function(){
  React.render(
    <RaisedButton label="hello" />,
    document.body
  );
});
```

`bin/rails s`でサーバを起動して、http://localhost:3000/ にアクセスするとhelloと書かれたボタンができていると思います。

# 参考文献

* [Material UI - Material Design React Components](http://callemall.github.io/material-ui/#/get-started)
* [Getting Started | React](http://facebook.github.io/react/docs/getting-started.html)
* [browserify-rails/browserify-rails · GitHub](https://github.com/browserify-rails/browserify-rails)
vim-dispatchでTeXファイルを非同期コンパイル

## はじめに

[vim-dispatch](https://github.com/tpope/vim-dispatch)というプラグインがあります. 

vimで非同期実行ができるプラグインです. 

裏でコンパイルと実行を行いながら, ファイルの編集ができます. 

ちょうど修士論文をtexで書いているので, 使ってみます. 


## VimからTeXコンパイル

私は, VimでTeXファイルの編集をしています. 

しかしTeXファイルのコンパイルは, やたら時間がかかります. 

特に, bibtexを使っていると, platexしてbibtexしてplatexしてplatexする必要があります. 

コンパイル用に, こんなシェルスクリプトを使っています. 

```{sh}
#!/bin/bash

## autobibtex 
file=$1
[ "$file" = "" ] && { echo "input file name!" ; exit 0 ; }

nkf -w8 --overwrite $file
filename=$(basename $file .tex)

platex -shell-escape $filename".tex"
bibtex $filename".aux"
platex $filename".tex"
platex $filename".tex"
dvipdfmx $filename".dvi"

find . | grep -E "$filename.(bbl|log|toc|dvi|blg|aux)" | xargs rm
```

platexからbibtexからplatexからplatex. アホです. 

時間がかかって作業が止まります. 辛いです. 

Vimから出ずに, ファイルを編集しながら裏でコンパイルできたら嬉しいです. 

[latexmk](http://konn-san.com/prog/why-not-latexmk.html)や[omake](http://omake-japanese.sourceforge.jp)で変更を監視して自動コンパイルする方法もあると思います. 

しかし, 自動コンパイルはちょっと鬱陶しいです. 自分のタイミングでコンパイルしたいです.

そこで, 非同期実行を可能にするプラグイン: vim-dispatchを使います. 

## やってみたこと

texコンパイル用のスクリプトを書いておいて, それをvim-dispatchで呼び出します.

コンパイル用のスクリプトをautobibtexとします. 先ほどの, platexしてからbibtexしてplatexするシェルスクリプトです. 

次に, vim-dispatchをインストールします. 

NeoBundleを使っていれば, .vimrcに1行書くだけですね. 

```{vimscript}
NeoBundle 'tpope/vim-dispatch'
```

そして, vimを起動して, $VIMRUNTIME/ftplugin/tex.vimを編集します. 

こう打てばtex.vimの編集ができるはずです. 

```{vimscript}
:e $VIMRUNTIME/ftplugin/tex.vim
```

tex.vimの中に, 2行だけ書き加えました. 

```{vimscrpti}
nnoremap ,r :w<cr> :Dispatch! autobibtex % <cr>
nnoremap ,,r :w<cr> :Dispatch autobibtex % <cr>
```

:Dispatch! コマンドで, 非同期実行できます.  

コンパイルメッセージも出てきません. 裏でコンパイルしてくれます. 

vim-dispatchのおかげで, コンパイル中もファイルの編集ができます. 

エラーがあって上手くいってなさそうな場合は, !マークを外したバージョンで実行してエラーメッセージを確認すればいいかなと思います. 

## 感想

だいぶ快適です. 

設定を3行書き加えただけで, コンパイルの時間が気にならなくなりました. 

今回はコンパイル用のシェルスクリプトを呼んでいますが, makeファイルを書くほうが標準的ですよね. make+vim-dispatchの方がカッコ良さそうです. 

ところで, 非同期ができても, PDF閲覧ソフトが自動更新してくれないと意味がないです. 

Linuxなら[evince](https://launchpad.net/ubuntu/+source/evince), Macなら[Skim.app](http://skim-app.sourceforge.net)などが, PDFの変更を検知して自動更新してくれます. 

Windowsは分かりません. TeXstudioとか使えばいいのでは.

以上です.
iOSで最も簡単にマルチスレッド処理を行う方法(NSOperationQueue)


# 目的
時間のかかる処理に関しては、メインスレッドとは別のスレッドで並列的に処理を行いたいことがある。
調べてみると、iOSアプリの実装で別スレッド処理を行う方法はいくつかみつかった。ただ、できるだけ簡単な記述を探すのに意外と時間がかかったのでメモしておく。

(2015/04/01 更新: swiftでの記述を追記)

# 最も簡単な実装

調べた内容を総合した所、NSOperationQueueを使うのが最も簡単のようだ。

## 別スレッドを一つだけ実行する場合

### Objective-C

```objc:sample.m
- (void)test {
    [[[NSOperationQueue alloc] init] addOperationWithBlock:^{
        NSLog(@"Some Operation.");
    }];
}
```

### swift

```swift:sample.swift
func test() {
    NSOperationQueue().addOperationWithBlock({ () -> Void in
        println("Some Operation.")
    })
}
```

## 別スレッドを複数実行する場合

### Objective-C

```objc:sample.m
- (void)test2 {
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    [queue addOperationWithBlock:^{
        NSLog(@"Some Operation");
    }];

    [queue addOperationWithBlock:^{
        NSLog(@"Another Operation");
    }];

    // 以降必要なだけaddOperationする
}
```

### swift

```swift:sample.swift
func test2() {
    let queue = NSOperationQueue()
    
    queue.addOperationWithBlock { () -> Void in
        println("Some Operation.")
    }
    
    queue.addOperationWithBlock { () -> Void in
        println("Another Operation.")
    }
    
    // 以降必要なだけaddOperationする
}
```


# 別スレッド処理を行える他の方法について

調べてみたところ、別スレッド処理を行うためには大きく分けて次の3つの方法があるらしい。

1. NSOperationQueueを使う方法
1. GCD(Grand Central Dispatch)を使う方法
1. NSThreadを使う方法

まず、GCDがNSThreadより良い点については以下のような理由があるようだ。

> GCDがよく利用されています。NSThreadだとスレッドの処理などを自前で書かないといけないのでコードが冗長になってしまい大変です。

出典: [8.2 Grand Central Dispatch · mixi-inc/iOSTraining Wiki](https://github.com/mixi-inc/iOSTraining/wiki/8.2-Grand-Central-Dispatch)

次は、GCDとNSOperationQueueのどちらを使うかに関して。今回調べた範囲では、基本的には高いレイヤー(Cocoa)の実装である後者を利用したら良いのではという印象。

今回見つけた関連URLを以下にまとめたので、もっと詳しい情報を得たい方は参考にしてみてほしい。

# 参考

ちくわとチワワはよく似てる — 非同期に処理を呼び出したい
http://thata.tumblr.com/post/20235526244

8.2 Grand Central Dispatch · mixi-inc/iOSTraining Wiki
https://github.com/mixi-inc/iOSTraining/wiki/8.2-Grand-Central-Dispatch

ios - NSOperation vs Grand Central Dispatch - Stack Overflow
http://stackoverflow.com/questions/10373331/nsoperation-vs-grand-central-dispatch

ios - Which is the best of GCD, NSThread or NSOperationQueue? - Stack Overflow
http://stackoverflow.com/questions/12995344/which-is-the-best-of-gcd-nsthread-or-nsoperationqueue

NSOperationQueue スレッドと処理の関係 - A Day In The Life
http://d.hatena.ne.jp/glass-_-onion/20110527/1306499056

【iPhoneアプリ】これを使えるようにならないと「マルチスレッド」について　概要編 - ゆるい感じのプログラムを書きたい。
http://kassans.hatenablog.com/entry/2014/03/13/125332

【iPhoneアプリ】これを使えるようにならないと「マルチスレッド」について　実装編 - ゆるい感じのプログラムを書きたい。
http://kassans.hatenablog.com/entry/2014/03/14/125810

【iPhoneアプリ】他にもまだまだあった「マルチスレッド」について　dispatch_xxxxx編 - ゆるい感じのプログラムを書きたい。
http://kassans.hatenablog.com/entry/2014/03/25/183257
SublimeTextのGoTo(command+p)で特定のディレクトリを表示しない方法

タイトルのままですが、Railsのgemをプロジェクト内にインストールし、SublimeTextでGoToしようとすると、ローカルgem内のファイルが大量に候補として表示されてしまいます。

以下のようにインストールし、

```Bash:bash
$ bundle install --path vendor/bundle
```

GoToしてみると、こんな感じ。
![routes_rb_—_hello_app.png](https://qiita-image-store.s3.amazonaws.com/0/2540/b65e8786-178a-2e5c-a9d5-65464823417f.png)



そこで、以下のようにsettingsを追加すると候補から除かれます。
Preferences -> Settings - User

```json:Preferences.sublime-settings
{
  "file_exclude_patterns": ["vendor/bundle/*"]
}
```

これで以下のように```vendor/bundle```以下のフォルダ、ファイルはGoTo対象外になります。
![routes_rb_—_hello_app_1.png](https://qiita-image-store.s3.amazonaws.com/0/2540/1f222119-66a4-7aca-2382-bb49e6a8213b.png)
Caveman2のCookieの値を変えたい

###やりたいこと###
Cookieの`Name`と値を変えたり，`httponly`を`t`にしたりしたい。

###app.lisp###
とりあえず`app.lisp`の`builder`内部の`<clack-middleware-session>`が，外部からいじれる部分だろうと思って`<clack-middleware-session>`をsuperclassとしたclassを定義してみました。

```cl:
(defclass <myapp-clack-session-state-cookie> (<clack-session-state-cookie>)
  ((session-key :initform :myapp.session
		:accessor session-key)
   (secure :initform nil
	   :accessor secure)
   (httponly :initform  t
	     :accessor httponly)))

(defclass <myapp-clack-middleware-session> (<clack-middleware-session>)
  ((state :initform (make-instance '<myapp-clack-session-state-cookie>)
	  :accessor state)))

(builder
 (<clack-middleware-static>
  :path (lambda (path)
          (if (ppcre:scan "^(?:/images/|/css/|/js/|/robot\\.txt$|/favicon.ico$)" path)
              path
              nil))
  :root *static-directory*)
 (if (productionp)
     nil
     (make-instance '<clack-middleware-accesslog>))
 (if (getf (config) :error-log)
     (make-instance '<clack-middleware-backtrace>
                    :output (getf (config) :error-log))
     nil)
;; <clack-middleware-session>
 <myapp-clack-middleware-session>  ;;ここだけ書き換え
 (if (productionp)
     nil
     (lambda (app)
       (lambda (env)
         (let ((datafly:*trace-sql* t))
           (call app env)))))
 *web*)
```
なんてしてみたものの変化なし。

試しに直に`clack.session.state`の`session-key`の値を書き換えたらcookieの値も変わりました。

```cl:
(defclass <clack-session-state> ()
     ((session-key :type keyword
                   :initarg :session-key
                   :initform :myapp.session ;; :clack.session
                   :accessor session-key)
      (sid-generator :type function
                     :initarg :sid-generator
                     :initform
                     #'(lambda (&rest args)
                         @ignore args
                         (clack.util:generate-random-id))
                     :accessor sid-generator)
      (sid-validator :type function
                     :initarg :sid-validator
                     :initform
                     #'(lambda (sid)
                         (not (null (ppcre:scan "\\A[0-9a-f]{40}\\Z" sid))))
                     :accessor sid-validator)))
```
`=> MYAPP.SESSION	e3d5067aceb466a9b01a04deb2170137c8bec3b0`



CLOS自体も大分忘れてるので混乱中…
とりあえずもうちょっとソース読み込みます…


###追記(2015-01-05-1310)###
builderを以下の様に書き換えたらできました。

```cl:
(builder
 (<clack-middleware-static>
  :path (lambda (path)
          (if (ppcre:scan "^(?:/images/|/css/|/js/|/robot\\.txt$|/favicon.ico$)" path)
              path
              nil))
  :root *static-directory*)
 (if (productionp)
     nil
     (make-instance '<clack-middleware-accesslog>))
 (if (getf (config) :error-log)
     (make-instance '<clack-middleware-backtrace>
                    :output (getf (config) :error-log))
     nil)
 ;; <clack-middleware-session>
 (<myapp-clack-middleware-session>
  :state (make-instance '<myapp-clack-session-state-cookie>))
 ;; <myapp-clack-middleware-session>
 (if (productionp)
     nil
     (lambda (app)
       (lambda (env)
         (let ((datafly:*trace-sql* t))
           (call app env)))))
 *web*)
```
`<myapp-clack-middleware-session>`の`:initform`が効いてない？？

とりあえず出来たけど疑問が残ってます。
Datatablesの使い方

Datatablesはテーブルをいい感じに表示してくれるjqueryプラグイン
[ココ](https://datatables.net/examples/basic_init/zero_configuration.html)にデモが、[ココ](https://github.com/DataTables/DataTables)にソースがある。

###とりあえず表示だけ

```html:datatables.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
  <script src="https://code.jquery.com/ui/1.11.1/jquery-ui.min.js"></script>
  <link rel="stylesheet" href="https://code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css">
  <!-- Datatables -->
  <link rel="stylesheet" href="./lib/DataTables/media/css/jquery.dataTables.min.css" >
  <script src="./lib/DataTables/media/js/jquery.dataTables.min.js"></script>
  <script>
    /* javascript */
  </script>
</head>
<body>
  <table id="datatables">
  </table>
</body>
</html>
```

```js:javascript
var Ggrd_Table = null;
$(function(){
  Ggrd_Table = $('#datatables').DataTable({
    "columns": [
      { "title": "aaa" },
      { "title": "bbb" },
      { "title": "ccc" },
    ]
  });
});
```

これでテーブルのヘッダ付きの枠組みだけ表示される。
内容を追加するには以下の方法で要素を追加していく。

###テーブルの行追加、削除
追加

```js
Ggrd_Table.row.add([
  "aaa",
  "bbb",
  "ccc"
]).draw();
```

削除

```js
Ggrd_Table.row(idx).remove().draw();
// idxはrow index number (0起算)
```

選択されている行を削除する

```js
// 「クリックした行の色を変化させる」をやった上で、
Ggrd_Table.rows( '.selected' ).remove().draw();
```

###クリックした行の色を変化させる(single select)
```js
$('#datatables tbody').on( 'click', 'tr', function () {
  Ggrd_Table.$('tr.selected').removeClass('selected');
  $(this).addClass('selected');
});

```
ImageMagick で convert 時にエラーが出た時

ImageMagick で png を bmp に変換しようとした時に、以下のエラーが出た時

```shell-session
$ convert image.png image.bmp
convert: unable to load module `/usr/local/Cellar/imagemagick/6.8.9-8/lib/ImageMagick//modules-Q16/coders/png.la': file not found @ error/module.c/OpenModule/1282.
convert: no decode delegate for this image format `PNG' @ error/constitute.c/ReadImage/501.
convert: no images defined `clion/simple_game_loop/images/font.bmp' @ error/convert.c/ConvertImageCommand/3187.
```

ImageMagick をアンインストールした後に、```--build-from-source``` オプションを付けて、インストールし直す

```shell-session
$ brew uninstall imagemagick
Uninstalling /usr/local/Cellar/imagemagick/6.8.9-8...
$ brew install imagemagick --build-from-source
```

## 参考
http://stackoverflow.com/questions/22715738/imagemagick-error
https://github.com/Homebrew/homebrew/issues/14325
java学び直しメモ part4 ～for文～

##今回の内容
[前回](http://qiita.com/yuukieiu/items/4c8d68f3a9ada72e8f7b)は，プログラミングの最重要要素の1つであるif文についてでした．

今回は，もう1つの最重要要素であるfor文について，学習していきます．

##for文とは
プログラムを書いていると，ある処理を繰り返し行いたい場面に遭遇することがあります．
例えば，1から7までの数字に3ずつかけて，その結果がほしい！（そんな場面ないか）とか…
1から7くらいなら地道に書いても書ききれそうですが，1から100,000,000,000まで，なんて言われたら，とても自力で書ける気がしません．
そんなときに，「3ずつかける」という動作を繰り返す（ループする），という命令が書けるのがfor文です．
for文はif文と同じブロック構造なので，if文と組み合わせることができ，とてつもない力を発揮できます．

##構文
if文に少し似ていますが，for文のほうがちょっとだけ複雑です．
for文は次のような構文で書きます．

```java:ForStatement.java
for (カウンタ初期値; ループ条件; カウンタ操作) {
    繰り返したい動作
}
```

**カウンタ**というのは，for文を用いて繰り返す際，繰り返す回数として利用するものです．
先程の例で言うと，1から7まで繰り返す場合は，1がカウンタ初期値となります．
次に，**ループ条件**は，繰り返しをする条件です．条件なので，真偽値でなければいけません．
最後の**カウンタ操作**とは，繰り返したい動作を**すべて行った後**，カウンタに対して行う操作です．
例で言えば，カウンタを+1（インクリメント）してから繰り返すことで，1，2，3，…と繰り返すことができ，ループ条件を「カウンタが7以下」という条件にすればいいわけです．
こんな感じ．

```java:ForExample1.java
for (int i = 1; i <= 7; i++) {
    System.out.println(i * 3);
}
```

##for文の基本
カウンタ初期値の部分で，変数の宣言を同時に行うことができます．
が，事前に宣言してある変数を使うこともできます．

```java:ForExample2.java
int i = 0;
for (i = 1; i <= 7; i++) {
    System.out.println(i * 3);
}
```

僕はメモリ節約のためにカウンタを使いまわしたりしますけど，使いまわすと可読性が落ちるので，他人に見られるコードでは使い回しはやめたほうがいいかもしれません．
また，for文の括弧内の要素は省略することができます．

```java:ForExample3.java
int i = 0;
for (;;) {
    System.out.println(i * 3);
}
```

このプログラムだと全く意味無いですが…
ここで注意するのは，**ループ条件が空だと無限ループする**という点です．
ForExample3.javaでは，無限に0が出力されます…
プログラムの無限ループは，それ以上プログラムが進むことができなくなるため，絶対に起こしてはいけません．
プログラムによっては，マシンに負荷をかけすぎて，壊してしまうことも…
このような事故を起こさないため，ループ条件には注意しましょう．
じゃあ省略できないようにすればいいじゃん…って僕は思うんですがね．

##break文
さて，for文のループ条件を空にした場合，無限ループになってしまうという問題がありますが，無理矢理ループを抜け出す，という命令が用意されています．
for文のようなループ処理を行うブロックの中に（for文以外にもループ処理ができる構文が存在するのです），「break;」と書くと，その行までプログラムが進むと，強制的にループを抜けることができます．

```java:ForExample4.java
int i = 0;
for (;;) {
    System.out.println(i * 3);
    break;
}
```

このようにすると，0が1回出力されてbreakによってループを抜け出します．
if文と組み合わせて利用することで，真価を発揮します．

```java:ForExample5.java
int i = 0;
for (;;i++) {
    System.out.println(i * 3);
    if (i >= 10000) {
        break;
    }
}
```

これで，iが10000以上になると，強制的にループを抜けられるようになりました．
breakはfor文よりもwhile文というループ構文で使うことが多いと思います．
ただ，breakを多用するプログラムは美しくないと言われます…

##ネスト構造
さて，最初にお話したとおり，for文はif文と同じブロック構造なので，ネスト構造にすることができます．

```java:ForExample6.java
for (int i = 0; i <= 100; i++) {
    for (int j = 0; ; j++) {
        System.out.println(i * j);
        if (j >= 20){
            break;
        }
    }
}
```
ネスト構造内でbreakを使うときは，抜けられるループは**1段階だけ**という点に注意です．
この場合，breakで抜けるのはjを使っているfor文のみであり，iを使っているfor文を抜け出すことができません．

##おわり
前回のif文と今回のfor文を組み合わせることで，できることの幅が広がると思います．
次回は，さらにできることが増えるようなものについてお話します．
ついでに今回説明できなかった拡張for文についても説明できるといいかな…？
教育担当向けネットワーク・サーバエンジニア育成メモ

開発と違って、コレ作って！みたいな典型的な物が少ないのでなんとなく思いついた順に書いてみました。
よくある内容ばかりかつテクニカルな事は少ないです。
ほぼ毎年1,2人の新人を教育してきたので、初めて教育担当になる方の助けとなればと思います。
また、指摘や追加等あれば連絡ください。

# はじめに
今回、新人のパターンを大きく次に分類します。

1.文系学校卒・他業種転向者(ITスキルゼロ)
2.理系学校卒でIT関係の勉強は学校以外でやっていない
3.趣味で自宅にサーバ数台運用している
4.開発系実務経験者
5.ネットワーク・サーバ系実務経験者

この中で3,5についてはタスクを与えていけば特に問題ないという経験から対象外とします。
2について、多くの場合は基本情報レベルの知識は学んでいると思います。が、基本情報レベルの話であってもついてこれる新人とそうでない新人が居ますので、1,4と同じレベルとみてください。

# 基本知識の習得
IPアドレスとは、Linuxとは、L2スイッチとは、といったレベルのこれから仕事をする上でベースとなる知識については、次の勉強をすれば多くの現場で基礎として事足りるかと思います。(書籍については個人的偏見によるものです)

1.基本知識
・基本(応用)情報技術者

2.実務レベル知識
・LPICレベル1
・Cisco CCNA
・マスタリングTCP/IP 入門編
・実践 パケット解析

# 現場固有(仕様・構成)の質問に対する回答
現場固有の話なので聞かれたことには根気良く回答してください。ただ、多くの場合は基本技術の積み重ねと思いますので、基本情報等の既に保有しているはずの知識と絡めてヒントを出していく形で回答しましょう。多くの新人は知識を仕事(タスクや問題等)と紐付けることが出来ないので、自分で考えて紐付け出来るように考えさせることが大切です。
また、新卒によくあることですが、説明後に「わかった？」「不明なところある？」と聞いても「大丈夫です」と元気良く返事する場合があります。9割以上の場合「わかったつもり」になっているだけなので、説明後は自身の言葉で説明してもらうようにしましょう。その際、言葉・文章的には問題無い場合でも説明した内容を復唱しただけがあるので、そこを**見抜いて**ください。
とはいえ単純に嘘を見抜くのは難しいので、説明に対して改めて別の質問をしてください。たいていの場合は答えられなかったりとボロがでます。

# タスク(仕事)の与え方
ネットワークやサーバの設定変更といった「定常的」「定型的」に行うタスクを実行してもらう際、次の事を理解して実行させるようにしましょう。

・タスクそのものの「目的」
・Linuxやスイッチ等で利用するコマンドの「動作」
・設定値の「意味」

最初の頃は仕方ないと思いますが、手順書やフロー等が定義されている場合、「理解せず」「何も考えず」にタスクがこなせる現場もあるかと思います。理解せずに「定常的」「定型的」なタスクを消化するのは**エンジニアではなくオペレータ**の仕事ですので、簡単なタスクを与える場合は注意しましょう。

# イレギュラー発生時の対応
私はテクニカル分野においてイレギュラー対応が成長する最も良い機会であると思っています。ただ、「対応出来る＝仕様・構成を理解している」事も前提になるので、新人には荷が重いです。時間をかけられる問題であれば対応させることもできますが、1分1秒を争う場合は無理な話なので事後の情報共有はもちろん、画面を後ろから見させる等、イレギュラーに関係させていくことが大切です。

# 習うより慣れろ
Webに書いてある、仕様はこうだからこうだ、といった話をしてくるケースも多々あるかと思いますが、個人的には「実際はどうか」が全てだと思ってます。単体では正解であっても実際の環境では違う、なんてことは日常茶飯事で、世界で最初にバグを発見するといったことも幾度か経験しているので、調べたことに対して必ず試験させるようにしてください。試験環境が無い現場もあるかと思いますがLinux系であれば仮想技術である程度までは環境は構築できるかと思います。FWやSW等は実機が必要、という場合も多々あり限界もあるかと思いますが・・・。コアな部分であればあるほど、提案時や設計時に試験環境準備の必要性をお客や上長に説明して準備できるようにしましょう。(自分達の為でもある)

# 何事も英語を参考にする
製品付属のマニュアルからWebの情報まで、新しい情報はもちろん、日本語訳が間違っていたりするので、英語の文書を参考するようにしましょう。もちろん英語の情報であっても実践・試験・確認するということは忘れずに実施することが最も重要です。

# サボりかたを教える
エンジニアのサボり方はとことん勉強して理解を深めていく以外に本当のサボりは出来ないと思ってます。
各種チェックコマンドからエクセル等、基本ではあるが的確・適切に利用していくことで最短で仕事が終わらせることが出来ると思ってます。。。

# スクリプトを書けるようにする(サーバエンジニア向け)
サーバエンジニアはシェルスクリプトに加えて幾つか書けるようにしたほうが良いです。
第一に自動化することが出来るということもありますが、仮想化技術やハードウェアベンダ等が提供しているAPIを使う場合に必要になってくることもあります。どの言語がいいか、というところは各種特徴があるので割愛しますが、チームで利用する言語は統一することをお勧めします。

# クライアントツールの紹介
既に利用されているメジャーなものばかりだと思います。こんなのもあるYOってのがあれば紹介してください！
なお、運用を行う端末がWindowsである前提です。

・Wireshark　言わずもがなのパケットキャプチャ・解析ツール。CLIで利用できるtsharkが利用できるようになると、ハイパワーなサーバマシンで同様な解析をすることも出来ます。
・BlackJumboDog　簡易的なサーバをサクっと立てられるソフト。WindowsでHTTPやSMTPを用意するのは面倒ですが、これならサクっと用意出来るのでちょっとした試験等で重宝したりします。
・exPing　まあ、Ping打ちっぱなしはこれですかね。
・RLogin　高機能ターミナルソフト。タブ型で頻繁に更新されているものですが、この辺は好みの問題なので他でも問題無いかと。
・
Cesiumで地理院タイル（地図/DEM）を使うライブラリ作成しました。

年末年始、諸事情でCesiumを使わないといけない事象が発生したので、ついでにCesiumで地理院地図（地図タイル及びDEM双方）を使うライブラリ作成しました。
Cesiumって何？の人はこちら => [Cesium:WebGL Virtual Globe and Map Engine](http://cesiumjs.org/index.html) WebGLを使って、Google Earthのような3D地球儀表示と2D地図表示の双方ができるライブラリです。
地理院タイルについてはこちら => [国土地理院地図タイル / Japan GSI tile API](http://portal.cyberjapan.jp/help/development/ichiran.html)

成果物はgithubで、[こちら](https://github.com/tilemapjp/Cesium-JapanGSI)に置いてあります。
動いているサンプルは[こちら](http://t.tilemap.jp.s3.amazonaws.com/cesium/index.html)。

以下、簡単に使用法説明。

### 基本的な使い方

    var viewer = new Cesium.Viewer('cesiumContainer', {
        imageryProvider: new Cesium.JapanGSIImageryProvider({
            layerLists: ["ort","relief","std"]
        }),
        terrainProvider: new Cesium.JapanGSITerrainProvider({}),
        baseLayerPicker: false,
        mapProjection: new Cesium.WebMercatorProjection(Cesium.Ellipsoid.WGS84)
    });
    var scene = viewer.scene;
    scene.globe.depthTestAgainstTerrain = true;

みたいな感じ。
この中で、JapanGSIImageryProviderとJapanGSITerrainProviderが作成したものです。

### JapanGSIImageryProvider

国土地理院の提供する地図画像タイル群から、好きなレイヤを組み合わせてCesiumの地図タイルレイヤを生成するライブラリです。  

#### プロパティ / Property 

* layerLists

地理院地図の使いたいレイヤIDを、配列で与えます。
全国レベルの画像セットがあるレイヤはプリセットされていますが、災害情報レイヤ等、一部しかないレイヤはプリセットされていません。
そのようなレイヤを使いたい場合は、以下のような感じで使いたいレイヤを定義してください。

    var layers = new Cesium.JapanGSIImageryProvider({
        layerLists: [{
            "id": "20130717dol",
            "zoom": "10-18",
            "ext": "jpg"
        },"relief","std"]
    });

列挙されたレイヤ中、提供されるズームレベルに重なりがある場合は、先に書いたレイヤが優先されます。

### JapanGSITerrainProvider

国土地理院のDEMタイル仕様から、Cesiumの地形を生成するライブラリです。

* heightPower

高度差の描画を強調したい場合、この値に1以上の値を与えると、その倍率だけ高さが強調された描画が為されます。
ただしもちろん、建物地物や飛行機の飛行経路等、その他の高度を持つ情報を描画する際は、そちらも同じ倍率を掛けないと相対高さがおかしくなります。

    var terrain = new Cesium.JapanGSITerrainProvider({
        heightPower: 2.0
    });

### Tips

どちらのライブラリも、Cesium.ViewerのbaseLayerPickerプロパティをfalse、viewer.scene.globe.depthTestAgainstTerrainプロパティをtrueにして使う事が推奨されます。
前者は、falseにしないと、Cesium標準の地図セット切り替えコントロールが出てきてしまい、設定した地図タイル、地形が反映されません。
後者は、trueにしないと、地形の地面の下に描画した地物も、透けて見えてしまいます。


バグ、拡張等ありましたら、どしどしパッチお願いいたします。
また、こんな機能欲しいという要望ありましたら、ご連絡ください。
QEMUに仮想PCIデバイスを追加する(3) : 開発/動作環境

開発/動作環境について説明します。

# Linux
QEMUで実行するLinuxを用意します。なんでも良いのですが、
頻繁に再起動することになるので
とりあえずBuildroot( http://buildroot.uclibc.org/ )を用いて最小限の環境を用意しました。

Buildrootには各種QEMU用のコンフィギュレーションが
configsディレクトリ以下に用意されているので、これを利用して
必要に応じて変更を加えます。

具体的にはソースコードをダウンロード、展開後に

```
	make qemu_x86_defconfig // i386 向け
	make menuconfig
		-> toolchain を glibcに (デフォルトではuClibc)
		-> buildoptions の number of jobs を 0 から8に
	make linux-menuconfig
		-> enable loadable module をチェク (デフォルトではoff)
	make
```
とします。他にも必要があれば make busybox-menuconfig などとします。
上記の通りにmakeを行うとカーネルイメージと(ブートローダを含まない)ext2 ルートファイルシステム（圧縮なし) が output/iamges 以下に作成されます。

このままではルートファイルシステムが小さいので

```
	dd if=/dev/zero of=image bs=10000 count=100 // (100M)
	mkfs -t ext2 -m 0 image

	mkdir mnt
	sudo mount -o loop,rw -t ext2 image mnt/
```
などとして適当にディスクイメージを作成、マウントした後にデータをコピーします
(Buildroot の設定からルートファイルシステムのサイズを変更する方法が
分からなかったためこうしました)。

# QEMU 
自分でコンパイルする必要があるので http://wiki.qemu.org/ 
よりソースコードをダウンロードしてきます。
単純にconfig, make をするとあらゆるアーキテクチャに対応したQEMUが作成されて
時間がかかるので、

```
	./configure --target-list="i386-softmmu"
```
として、i386 用のみをコンパイルするようにします。実行ファイルは
i386-softmmu/qemu-system-i386 となります。

## 追加仮想デバイスのコンパイル

hw/char 以下にキャラクタデバイスの実装ファイルがあります。
今回はここに新たに作成したファイル(test_pci_device.c)を置きました。
同ディレクトリにある Makefile.obj に 

```
	obj-$(CONFIG_PCI) += test_pci_device.o
``` 
を追加します(因みにi386-softmmu/config-device.mak で CONFIG_PCI=y となっています)。
これにより test_pci_device がmake時に一緒にコンパイルされます。

コンパイルしたQEMUを実行するには、

```
	qemu-system-i386 \
		-kernel bzImage \
		-hda image \
		-append "console=ttyS0 root=/dev/sda rw panic=1"
		-nographic \
		-no-reboot \
		-device test_pci
```
などとします(パス/ファイル名は適当に変えてください)。
ブートローダ無しで起動が行えます。
-nographic オプションを使用することでCUI環境のみでQEMUを実行できます。
-no-reboot とカーネルオプション(-append 以下)の panic=1 を利用することで、カーネルパニック1秒後に
QEMUが終了します。作成したPCIデバイスを -device オプションで渡します。

なお、この場合 ctrl-a+c でモニタ画面に移動でき
(GUI 版は alt-ctrl-2)、 ctrl-a+x でQEMUを終了できます。
モニタ画面では各種コマンドを実行できます。例えば、info pci
とタイプすると接続している PCIデバイスの状況が確認できます。

---
はじめ: [(1) 作ったもの]
(http://qiita.com/rafilia/items/f7646d12212da2a85bd8)

前: [(2) 前提知識 (PCI / デバイスドライバ)](http://qiita.com/rafilia/items/7e30f1119614964ce4c9)
次: [(4) 仮想デバイス/ドライバの登録]
(http://qiita.com/rafilia/items/ba73703babb92276b55a)
Jinja2とAngularJSの変数スコープの競合を解決する方法

AngularJS と Jinja2 は HTML に変数スコープを {{...}} という二重の波括弧で囲う構文仕様になっています。よって、 Python のフレームワークで使われる Jinja2 で AngularJS を書きたい場合に HTML に AngularJS の変数スコープを書くと競合してしまい, AngularJS の変数スコープは無効化されてしまいます。

AngularJS側の変数スコープのデリミタ({{...}})を変更する方法は[naoiwataさんのエントリー](http://qiita.com/naoiwata/items/61dd023355c7759a68ac)でみつかったのですが、Jinja2側を変更したい場合のやり方がわからなかったので調べてみた。


・・・で結論。

最初の[環境設定](http://jinja.pocoo.org/docs/dev/api/#high-level-api)で
 **variable_start_string**と **variable_end_string**を変更をすればいいらしい。



というわけでGAEのwebapp2フレームワークからJinja2のテンプレートエンジンを使うスクリプトを書いてみた。

```index.py
import os
import webapp2
import jinja2

JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__))
	,extensions=['jinja2.ext.autoescape']
	,variable_start_string='[['
	,variable_end_string=']]'
   ,autoescape=True)

class MainPage(webapp2.RequestHandler):

    def get(self):
        template_values = {
            'test': 'hello Jinja2'
        }

        template = JINJA_ENVIRONMENT.get_template('index.html')
        self.response.write(template.render(template_values))
        
app = webapp2.WSGIApplication([('/', MainPage)],
                              debug=True)
```

※webapp2でJinja2を使う方法は[ココ](https://cloud.google.com/appengine/docs/python/gettingstartedpython27/templates)を参照。

```index.html
<!DOCTYPE html>
<html ng-app="MyApp">

  <head>
    <script src="https://code.angularjs.org/1.3.5/angular.js"></script>
    <script src="script.js"></script>
  </head>

  <body>
    <div ng-controller="mainCtrl">
      <p>{{test}}</p>
      <p>[[test]]</p>
    </div>
  </body>

</html>
```


```script.js
var myModule = angular.module("MyApp", []);
myModule.controller('mainCtrl',['$scope', function($scope){
  $scope.test = "hello angularjs";
}]);
```

うまくいくとブラウザ上で*hello angularjs*と*hello Jinja2*が表示されます。

GAEにアップロードすればappspot.com上でAngularjsが使えるようになります。
シェルスクリプトを書く際の心得

### 概要

シェルを書く時のMY心得のようなものを書き殴ってみた。あまり洗練されてません^^;。
プログラミング一般に通じるところもあるかも。

こちらの投稿に触発されました。
[シェルスクリプトコーディングルール](http://qiita.com/mochidamochiko/items/cd72bab51a2f9c74cf77
)（@mochidamochikoさん）

### 心得１．適切な変数化、関数化
＜変数について＞
例えば、hostsから、あるホスト名のIPアドレスを抽出する処理があるとする。この場合、以下が適切な変数の使い方だ。

```bash:①適切な変数の使い方
host=$1
grep ${host} /etc/hosts | awk '{print $1}'
```

これを以下のようにする人がいる。

```bash:②やり過ぎな例
host=$1
config=/etc/hosts
grep ${host} ${config} | awk '{print $1}'
```

違いがわかるだろうか。①に比べ②は「何だか読みづらい」と感じるはずだ。
変数は値が見えないためどうしても変数名から内容を推測せざるを得ず、適切な名前を付けないと、コードの可読性を低下させる要因になってしまう。

適切な名前かどうかは、そのコマンドライン全体を見て何をやっているかを、変数の値を見なくてもわかるかどうか、が基準になる。意味が取れなければ変数名が適切でない。
上記の例だと、①はhostsに対しホスト名をキーにgrepしようとしていることがわかる。おそらくIPアドレスを抽出しようとしているのだろう、と想像できる。
しかし、②ではそもそも何をしようとしているのか分からない。grepコマンドの理解に必要な、処理対象のファイル名を変数configが隠してしまっているためだ。
コマンドの意図の理解を邪魔しないようにするには、変数configがhostsを指定しているということが分かるようにしなくてはならない。付けるなら、おそらくhostsという名前になるだろう。
その名前じゃ直接指定しても同じじゃん！変数化する必要ないじゃん！その通りだ。だから、②のコードは間違いなのである。
ただ、ファイル名の変数化が全くの無駄というわけではない。そのファイルが複数あり、切り替えて使ったりする場合は変数化する余地がある。

＜関数について＞
シェルスクリプトにおける関数はコマンドと同等であるため、いっぱしのUnixコマンドとみなせる設計とすること。
つまり具体的な単機能を提供しフィルタとして扱える必要がある。

### 心得２．コードの最後まで到達する処理を戻り値0（正常終了）としてコーディングする
運用シェルでれば、基本、構造化プログラミングを意識した作りにすると読みやすいコードになる。

```bash:シェルを書く時の基本的な流れ
#!/bin/sh
if …; then
    exit 8  # 異常終了1
fi
if …; then
    exit 16 # 異常終了2
fi
…
exit 0      # 正常終了
```

### 心得３．変数宣言の意味は値のセットだけにあらず
標準のスコープがグローバルだからといって、変数を事前に宣言しておかないと、読む人を混乱させるコードになる。
制御構文や関数の内外で使われる変数は、セットする値が無いとしても事前に宣言しておく。

```bash:例えば…
val=        # 値は空でいいので、これ以降で使いますよと宣言しておく
if …; then
    val=`…` # 制御文の外で使うのだから、ここでいきなり登場させない
fi
echo ${val}
```

### 心得４．判定処理は一行に詰め込み過ぎない
if文を使うより||、&&などで一行にまとめた方が読みやすいのは確か。でも読みやすいのは1〜2個の連結まで。3つも4つもコマンドを連結するとめちゃくちゃ読みにくくなる。判定に用いる場合は過度にコマンドを連結しないこと。もしくは適度に改行を入れること。
また、同じ理由で `if grep …; then` はコマンドの長さと相談する。場合によっては以下のように分割する。

```bash:このように分割した方が良い場合もある
grep …
if [ $? -eq 0 ]; then
```

### 心得５．正規表現を乱用しない
grepやsedは重い。それは正規表現のマッチ処理自体が重いから。表現できるものが多ければ多いほどその仕組みの処理は重くなる。当たり前のことだ。
正規表現はあまりに何でも表現できるものだから、できる限り正確に、汎用的に表現しようと事細かく指定する人がいる。でも運用を考えればありえない指定だってある。それは意味のある細かさか？無駄に処理を重くしていないか？と必ず自分に問うようにしよう。

### 心得６．異なる制御文・コマンドを織り交ぜる
可読性のため。UNIX使いには当たり前のことかもしれないが、if文の中にif文を入れて、更にその中にif文を……などとすると、可読性が恐ろしく低下する（そもそもネストを重ねること自体あまり褒められたものではない）。
そういう場合、最後の判定を||や&&で1行にするとぐっと読みやすくなる。
読む側の気持ちになって、飽きの来ないコードにすること。

```bash:ダメな例
if …; then
    if …; then
        if …; then
            exit 8
        fi
    fi
fi
```

```bash:上のコードよりは読みやすい例
if …; then
    if …; then
        … || exit 8
    fi
fi
```

### 心得７．汎用コマンドより専用コマンドを用いる
これも可読性のため。例えば、何でもかんでもawkで処理しない。`awk '{print $1}'` でなく、`cut -d' ' -f1` とする。
awkを使いこなせる人はかなり少ない。ましてや読める人はもっと少ない。現実を見よう。（まあ、このくらいならわかると思うけどね）

### 心得８．運用シェルなら性能より可読性・移植性
いざシステムに障害が起きた時、シェルを見て処理を追うという場面は多い。その際、そのシェルが何をしているのか、一秒でも早く理解できるコードにすることが重要。
また、システム更改などでは旧システムや他システムのシェルが流用されることも多い。移植されることを考慮して、BourneShellと可能な限り互換性があるシェルを書く。

### 心得９．業務シェルならbash. bashを使うなら独自拡張の使用を厭わない
可読性はもちろん考慮する必要があるが、bashを使うなら他シェルとの互換性など意識せず、独自拡張をバンバン使うべき。でなければbashを使う意味がない。
yum updateでTransaction Check Error


```bash:conoha
sudo yum update -y
Transaction Check Error:
  file /usr/lib64/libmysqlclient.so.16.0.0 from install of Percona-Server-shared-51-5.1.73-rel14.12.624.rhel6.x86_64 conflicts with file from package Percona-Server-shared-compat-5.1.68-rel14.6.551.rhel6.x86_64
  file /usr/lib64/libmysqlclient_r.so.16.0.0 from install of Percona-Server-shared-51-5.1.73-rel14.12.624.rhel6.x86_64 conflicts with file from package Percona-Server-shared-compat-5.1.68-rel14.6.551.rhel6.x86_64
```
タイトルの通り被るので、古い方を削除。

```bash:conoha
yum remove Percona-Server-shared-compat-5.1.68-rel14.6.551.rhel6.x86_64

sudo yum update -y
```
rskkservの現行化とGoogle CGI API for Japanese Inputのサポート

# 動機
アップフロントの偉い人、「やまざきなおき」さん(通称山ちゃん)の「やまざき」は「山﨑」と書くのです。この「﨑」をSKKからも入力したいなと思ったのが発端でした。

# DDSKK
DDSKKでの対応は簡単でした。

```el
(setq skk-extra-jisyo-file-list
      (list ; いろいろ辞書指定
	    '("/usr/share/skk/SKK-JISYO.JIS3_4" . euc-jisx0213)
            ; いろいろ辞書指定
)
```

のように書くだけでした。

# fcitx

こちらはいろいろ悩みました。「﨑」だけなら、```SKK-JISYO.JIS3_4``` をUTF-8に変換してやってエンコードを指定して辞書指定してあげればすみました。

でも「髙橋」「髙島屋」のような「はしご高」も入力できるようにしたくなりました。この「はしご高」はUTF-8にしかないようなので、よし、この際、SKKサーバをrskkservにして、Google CGI API for Japanese Inputにも対応しようと思ったのでした。SKKの辞書にはたぶん「はしご高」はないからです。(調べていません。)

## rskkserv

1. [tarao/rskkserv](https://github.com/tarao/rskkserv) をforkして現在の環境に合わせて改変し、ビルドできるようにした。
2. [Google CGI API for Japanese Inputを使って日本語変換 - Qiita](http://qiita.com/konnyakmannan/items/a3d0f43e7796ec67ad78)
を参考にして、rkkservに```GOOGLEDic```というクラスを追加。(ありがとうございました。)
3. SKK辞書をUTF-8に変換して、rskkserv.confファイルに追加。

SKK-JISYO.JIS3_4はUTF-8に変換できない文字もあるようなので、

```shell-session
iconv -c -f EUC-JISX0213 -t UTF-8 /usr/share/skk/SKK-JISYO.itaiji.JIS3_4 > SKK-JISYO.itaiji.JIS3_4.utf-8 
```
のように```-c```オプションを指定して、無視してしまいました。

rskkservの修正は[duloxetine/rskkserv](https://github.com/duloxetine/rskkserv/tree/master)に置いておきました。

## fcitx-skk
1. [duloxetine/fcitx-skk-plus](https://github.com/duloxetine/fcitx-skk-plus)のデフォルトの文字コードをUTF-8にしました。
2. ```~/.config/fcitx/skk/user.dict```をUTF-8に変換。このとき先頭行のマジックコメントも```euc-jp```から```utf-8```に変更しておきましょう。

## あとは
あとはそれぞれ```/usr/local/sbin/skkserv.rb```を起動したり、
```fcitx -r```で再起動したりすると、試行錯誤の上、使えるようになるかと思います。

# 効能

- 「山﨑」が変換できる。
- 「髙橋」「髙島屋」が変換できる。
- ▶や⏎なども変換できる。「扃る」(ひきこもる)も変換できる。

どれも必要な人には必要ですが、いらない人はいらない機能ではあります。

# 課題

- 毎回Googleにアクセスに行ってしまう。ローカルの辞書に候補がないときだけGoogleに行ってほしい。単語登録直前のところで、Googleにアクセスするのがいいと思うが、そのやり方がちょっとわからない。
- Googleにはhttpでアクセスしています。httpsではありません。
- メモリを多く消費します。でも現在の環境では悩むほどではないかもしれません。

課題が解消される見込みはありません。

# 補遺

SKKの皮をかぶったGoogle日本語入力ではないかという思いを禁じえません。でも有名人などの固有名詞の入力にはGoogle CGI API for Japanese Inputは便利なんですよね。痛し痒しです。
SublimeText3でSimpleRailsNavigatorを追加する方法

noklesta/SublimeRailsNav
https://github.com/noklesta/SublimeRailsNav/
Railsのプロジェクト内のModel, Controller, View, Helperなどをリスト表示してくれるパッケージです。結構便利そう。

SublimeText3だとPackageControlで追加することができないので、以下の通り、追加してみました。

```bash:bash
# クローンする
$ git clone http://github.com/noklesta/SublimeRailsNav

# クローンしたディレクトリへ移動
$ cd SublimeRailsNav

# 対象のブランチへチェックアウト
$ git checkout ST3

# Packagesのディレクトリに移動
$ mv SublimeRailsNav ~/Library/Application\ Support/Sublime\ Text\ 3/Packages
```

キーバインドはこちらで設定
Preferences -> PackageSettings -> Key Bindings - User

```json:Default(OSX).sublime-keymap
[
  { "keys": ["super+ctrl+m"], "command": "list_rails_models" },
  { "keys": ["super+ctrl+c"], "command": "list_rails_controllers" },
  { "keys": ["super+ctrl+v"], "command": "list_rails_views" },
  { "keys": ["super+ctrl+h"], "command": "list_rails_helpers" },
  { "keys": ["super+ctrl+x"], "command": "list_rails_fixtures" },
  { "keys": ["super+ctrl+t"], "command": "list_rails_tests" },
  { "keys": ["super+ctrl+i"], "command": "list_rails_javascripts" },
  { "keys": ["super+ctrl+y"], "command": "list_rails_stylesheets" }
]
```