OmniAICreator/Qiita-1.07M huggingface dataset:
可変長引数で受け取った値を可変長引数としてメソッドに渡す

# 概要
GroovyでinvokeMethod使うときに受け取った引数をそのまま他のメソッドに可変長引数として使いたい時に少しハマったので共有します。

例えばHogeクラスを拡張したくてinvokeMethodでクロージャを定義するとき、2つ引数を定義すると後者にメソッドの引数として与えられた値が入ります。

```groovy
Hoge hoge = new Hoge()

hoge.metaClass.invokeMethod = { name, args ->
    /* do something */
}
```

この例ではargsが可変長引数になっており、クロージャからはリストとして扱えます。
しかしこのままではリスト故に次のように可変長引数を期待するメソッドにそのまま代入しようとすると1引数のリストとみなされてしまいます。

```groovy
hoge.metaClass.invokeMethod = { name, args ->
    something(args)
}

/* ...... */

void something(String... args) {
    /* do something */
}
```

ここでどうすればよいのかハマってしまい色々な情報を探しました。
色々と試行錯誤しているうちにリスト展開演算子を使って次のように書くとうまくいくことを発見しました。

```groovy
hoge.metaClass.invokeMethod = { name, args ->
    something(*args)
}
```

argsの前に*(アスタリスク)をつけただけです。
リスト展開演算子はその名の通りリストを展開してフラットにするもので例えば```def a = [1,2,3]```といったリストがあった時に```[ *a,4,5,6 ]```とすると```[1,2,3,4,5]```となります。(この場合```[a,4,5].flatten()```としてもよいですが)
演算子の存在は知っていましたが、リストの中でしか使わないものだと思っていましたが、このように引数の展開もできました。

ところで今年はGroovy関係のアドベントカレンダーはないのでしょうか？
あるのでしたら何か書こうかと思っていたのですが……
npmでgypのエラーが出た時の対処法


# 概要
npmを使っているとある時、```config python error```みたいなものが出てきました。(スクショ撮り忘れた。)

# 解決方法
とっても簡単で以下のものを設定したらよい。

```
$ npm config set python /usr/local/var/pyenv/shims/python
```
unicorn で graceful restart するときに worker ready を待つ

適当にググると以下のようなコードが出てきてこのように使っていたのだけれど、これだと worker が ready になる前に oldbin に QUIT を送ってしまう

```ruby
before_fork do |server, worker|
  old_pid = "#{server.config[:pid]}.oldbin"
  if old_pid != server.pid
    begin
      sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
      Process.kill(sig, File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
    end
  end
end
```

ので以下のようになんとかした。

```ruby
servers = []

def wait_for_workers_are_ready(servers, old_pid)
  Thread.new do
    loop do
      unless servers.inject(false) {|memo, s| memo ||= !s.orig_app.nil? }
        Process.kill(:QUIT, File.read(old_pid).to_i)
      end
      Thread.pass
      sleep 3
    end
  end
end

after_fork do |server, worker|
  servers << server
  begin
    old_pid = "#{server.config[:pid]}.oldbin"
    if old_pid != server.pid && (worker.nr + 1) >= server.worker_processes
      wait_for_workers_are_ready servers, old_pid
    end
  rescue Errno::ENOENT, Errno::ESRCH => e
    $stderr.puts "#{e.class} #{e.message}"
  end
end
```

美しくない。
【C#】現在時刻から直後のきりの良い時刻（5分、10分、15分・・・）を取得する。

別のプログラムを書いていて、思いついたのでここに記載。

###解説
現在時刻を秒に直して、300のmodを取ることで、直前のきり良い時刻からの経過時刻を取得。300からそれを引くことで、きりの良い時刻までの時間を取得。現在時刻にそれを加える。

```csharp
using System;

public class Hello{
  public static void Main(){
    int addSeconds = 300 - (DateTime.Now.Minute*60 + DateTime.Now.Second)%300;
    DateTime d = DateTime.Now.AddSeconds(addSeconds);
    System.Console.WriteLine(d.ToString());
  }
}
```
phpのcurlの結果はデフォルトで"出力"されるので注意

php上級者には当たり前なんだろうけどハマったので。

# 気付いた経緯

1. ファイルをダウンロードさせるphpの処理の途中で別サーバのAPIをcurlで叩く処理を追加
1. テストしている時にダウンロードしたデータの先頭にAPIのレスポンスボディが混ざっているのに気付く
1. 😇

# 対策

CURLOPT_RETURNTRANSFER をtrueにする。なぜデフォルトで出力されるのか理解に苦しむ。。

```php
$ch = curl_init ( "http://host/path" );
curl_setopt ( $ch, CURLOPT_POST, true );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $param);
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
curl_exec ( $ch );
curl_close ( $ch );
```
MacOSX > SourceTree > Error encountered > 'git status' failed with code 5:'dyld: lazy symbol binding ... > 古いバージョンに戻して対応

```txt:動作環境
MacOS X 10.8.5
SourceTree 2.0.5.6
```

##問題

SourceTreeのバージョンをあげたら、以下のエラーが出てどうにもできなくなった。

![151117-linemonitor-UI__Git_.png](https://qiita-image-store.s3.amazonaws.com/0/32870/f4dd483c-0e79-6b6b-cb06-bbfff1db78ce.png)

##復旧方法

参考 https://answers.atlassian.com/questions/290155/restore-older-version-of-sourcetree

上記参考のページに記載されているように、以下のように古いバージョンを取得。

http://downloads.atlassian.com/software/sourcetree/SourceTree_2.0.0.dmg

実際に行った手順は以下

1. アプリケーションフォルダからSourceTreeを削除
2. 古いバージョンのdmgファイルを取得. dmgを開く
3. 開いたフォルダ内でSourceTreeをアプリケーションフォルダに移動
4. SourceTreeを開く

##リリースノート

Mac版のリリースノートは以下
https://www.sourcetreeapp.com/update/ReleaseNotes.html

とりあえずv2.0.0では問題が起きなかった。

どのあたりまで上げるかは微妙。

## v2.0.5.5で様子見

結局、Bug Fix関連の検討からv2.0.5.5にした。

http://downloads.atlassian.com/software/sourcetree/SourceTree_2.0.5.5.dmg

SourceTreeのクラッシュにより.git/index.lockファイルが残ってしまったとメッセージがでたので、index.lockファイルをターミナルから削除した。

その後、とりあえず正常動作している。
MutationObserverでのDOMのスタイルの監視

javascriptのイベントでDOMのスタイルの変更を検知できないかと思って、下記ブログを見つけてそれを元に作成。

MutationObserverでDOMを監視して、変更があったらeventをなげる。

よくわかっていないので、結構間違っているかもしれない。

なおこのサンプルコードはjQueryは必須です、javascriptだけでも書けますが、私はjQueryでDOMを捕まえるのがクセになっているので。

あとこのMutationObserver、IEは11から対応のようです。

~~~javascript
/* 1 Dom Style Watcher本体 監視する側*/
var domStyleWatcher = {
  Start: function(tgt, styleobj){
    //発生
    function eventHappen(data1, data2){
      var throwval = tgt.css(styleobj);
      tgt.trigger('domStyleChange', [throwval]);//eventを投げる
    }
    //監視の登録
    var tge = tgt[0];//jQueryオブジェクトをelementに変えてる
    var filter = ['style'];//styleを見る
    var options = {//監視オプション
      attributes: true,
      attributeFilter: filter
    };
    var mutOb = new MutationObserver(eventHappen);//監視用インスタンス作成
    mutOb.observe(tge, options);//監視開始
    return mutOb;//一応return
  },
  Stop: function(mo){
    mo.disconnect();
  }
};

/* 2 ターゲット 監視される側*/
var target = $('#id');//ターゲット

//イベントが起きた際に行うことを設定
function catchEvent(event, value){
  console.log('イベントキャッチ');
  console.log(event);
  console.log(value);
}

var styleobj = 'top';//style内のほしい値

target.on('domStyleChange', catchEvent);//イベントを登録
var dsw = domStyleWatcher.Start(target, styleobj);//監視開始
//domStyleWatcher.Stop(dsw);//監視終了

/* 3 テスト*/
target.css('top',50);//ここでevent('domStyleChange')が起こる
~~~

参照
> http://blog.gutyan.jp/entry/2014/09/06/MutationObserver
小ネタ：PDOでスムーズにIN句を扱う方法


array_fillで要素数分のプレースフォルダを作成し、implodeで一気にクエリ用の文字列にする戦略。

```php
<?php
$array = [1, 2, 3, 4, 5];
$query = sprintf('SELECT * FROM test_table WHERE id IN (%s)', implode(', ', array_fill(0, count($array), '?')));
$stmt = $pdo->prepare($query);
$stmt->execute($array);
foreach ($stmt as $row) {
	//...
}
```

クエリ本体を動的に作成するという、セキュリティ上の禁じ手を選択してはいるが次の2点からセキュリティ上の問題は無いと判断している。

- クエリ上に外部入力値が載る事は無いため、SQL Injectionが成立しない
- 大量の要素を持つ配列への対策はクエリ構築前に、配列自体に対するバリデーションで対応すべきなので、ここでの問題には当たらない

## 最大2次元までの配列でスムーズにプリペア― => ぽっぽーんする方法

```php
<?php
$array = ['app_no' => 1, 'group_ids' => [1, 2, 3, 4, 5], 'key_no' => 3];

$query = 'SELECT * FROM test_table WHERE id app_no = %s AND group_ids IN (%s) AND key_no = %s';

$placefolders = [];
$values = [];
foreach ($array as $element) {
	if (is_array($element)) {
		$placefolders[] = implode(', ', array_fill(0, count($array), '?'));
		$values = array_merge($values, $element);
	} else {
		$placefolders[] = '?';
		$values[] = $element;
	}
}

$stmt = $pdo->prepare(vsprintf($query, $placefolders));
$stmt->execute($values);
foreach ($stmt as $row) {
	//...
}
```
MACを利用して便利だと思ったことをまとめ

# MAC利用するTechniques（まとめ中）

* 隠しファイルを表示する（Show hidden files in folder）

  Console/Terminalを開き、以下のコマンドをタイプ、Enter!

      defaults write com.apple.finder AppleShowAllFiles YES

* 全画面をキャプチャーする（Save entire screen shot）

      Press Command (⌘)-Shift-3. The screenshot is added to your desktop.

* Capture some of your screen

Press Command (⌘)-Shift-4, and then drag the crosshair pointer to select the area. Hold Shift, Option, or the Space bar while you drag to resize the selection area.

* パッケージをインストールする（install package for MAC）

      brew install 'package_names'

* ディレクトリをツリーのように表示する（open directory）

      tree

* Start apache on MAC

      sudo apachectl start

Check by accessing http://localhost

* Zoom

  - Mouse zoom: Control + Option
  - Command + "+"

* Spotlight

  - Control + space

* iTerm2入れてみました
 - 色を変えたりして、便利です！http://iterm2colorschemes.com/

# References

* [Capture screen in MAC - support page](http://support.apple.com/en-us/HT201361)
* [install php and mysql and apache](http://jason.pureconcepts.net/2012/10/install-apache-php-mysql-mac-os-x/)
ERAlchemyでPostgreSQLからER図生成

# ERAlchemy
[Alexis-benoist/eralchemy](https://github.com/Alexis-benoist/eralchemy)
> ERAlchemy generates Entity Relation (ER) diagram (like the one below) from databases or from SQLAlchemy models.

これで手軽にER図が生成できる。

## インストール
- CentOS 7
- Python2.7

pip をインストールしていなければ以下参照
[CentOS7にpipをインストール。ついでにiPythonも。 - Qiita](http://qiita.com/takeyamajp/items/95f8da39b468eebef094)

```
yum install gcc python-devel graphviz-devel
pip install eralchemy
```

で、postgresに接続するためにPsycopgをインストール
[PostgreSQL + Python | Psycopg](http://initd.org/psycopg/)
```
yum install postgresql-devel
pip install psycopg2
```

以上、準備完了

## PDFを出力
```
eralchemy -i 'postgresql+psycopg2://[username]:[password]@[host]:[port]/[database]' -o hoge.pdf
```

ちなみに対応形式は

- .png(PNG)
- .pdf(PDF)
- .dot(GraphViz)
- .er(markdown)

### スキーマ指定について
以下のようにスキーマを指定して出力できるが…
```
eralchemy -i 'postgresql+psycopg2://[username]:[password]@[host]:[port]/[database]' -s [schema] -o hoge.pdf
```

リレーションのひも付けがうまくできていない。
```
eralchemy -i 'postgresql+psycopg2://[username]:[password]@[host]:[port]/[database]' -s [schema] -o hoge.dot
```
:arrow_up: で出力されたファイルを確認してみると。

```
～～～
"[schema].User" [label=<<FONT FACE="Helvetica">...
～～～
"[schema].TeamMember" [label=<<FONT FACE="Helvetica">...
～～～
"User" -- "[schema].TeamMember" [taillabel=<<FONT>0..N</FONT>>,headlabel=<<FONT>{0,1}</FONT>>];
～～～
```

リレーションのひも付けを記載しているところで親のみスキーマ名が付与されていない。
原因は後でおってみる。
DOM ElementからのXPath取得関数を作ってみた


Firebugの"XPathをコピー"と互換性があります。
いわゆるこれ↓
![これ.png](https://qiita-image-store.s3.amazonaws.com/0/81573/77daf83b-f3ec-dd74-beb7-3471422ad781.png)

要素を右クリックして、"XPathをコピー"した場合と同じ文字列を取得できます。

## 実装

```javascript
/**
 * エレメントノードからxpathを構築します。
 *
 * @param	Node	element_node	xpath構築元のelement node
 * @returns	element nodeまでのxpath
 */
function getXpathByElementNode (element_node) {
	var NODE_TYPE_ELEMENT_NODE = 1;

	if (element_node instanceof Array) {
		element_node = element_node[0];
	}

	if (element_node.nodeType != NODE_TYPE_ELEMENT_NODE) {
		throw new ErrorException('nodes other than the element node was passed. node_type:'+ element_node.nodeType +' node_name:'+ element_node.nodeName);
	}

	var stacker = [];
	var node_name = '';
	var node_count = 0;
	var node_point = null;

	do {
		node_name = element_node.nodeName.toLowerCase();
		if (element_node.parentNode.children.length > 1) {
			node_count = 0;
			node_point = null;
			for (i = 0;i < element_node.parentNode.children.length;i++) {
				if (element_node.nodeName == element_node.parentNode.children[i].nodeName) {
					node_count++;
					if (element_node == element_node.parentNode.children[i]) {
						node_point = node_count;
					}
					if (node_point != null && node_count > 1) {
						node_name += '['+ node_point +']';
						break;
					}
				}
			}
		}
		stacker.unshift(node_name);
	} while ((element_node = element_node.parentNode) != null && element_node.nodeName != '#document');

	return '/' + stacker.join('/').toLowerCase();
}
```

## 実証

[PHP - mb_strwidthの返す値が怪しかったので調べてみた - Qiita](http://qiita.com/ProjectICKX/items/984571a608db89f29cfd)のHTMLを対象に検証。

### 元のXPathを取得

画面上での指定は次の画像の通り。

![03.png](https://qiita-image-store.s3.amazonaws.com/0/81573/e6257b12-3a17-d04a-ec74-459bd7aec384.png)

Firebugでの指定では次の画像の通り。

![02.png](https://qiita-image-store.s3.amazonaws.com/0/81573/c8d00ad2-0108-2c73-1436-a27886e88af4.png)

この状態で"XPathをコピー"すると次の結果が得られる。

```javascript
/html/body/div[3]/article/div[2]/div/div[1]/section/table[1]/tbody/tr[3]/td[2]
```

### XPathからエレメントを取得し、エレメントからXPathを取得する

Firebugのコンソールを使う

![04.png](https://qiita-image-store.s3.amazonaws.com/0/81573/53674d48-10b2-e259-f1cb-b768e1806b32.png)

関数追加して処理を実行して・・・

![05.png](https://qiita-image-store.s3.amazonaws.com/0/81573/95b55aa2-0172-43e8-1675-e9c3d7c04ad5.png)

```javascript
/html/body/div[3]/article/div[2]/div/div[1]/section/table[1]/tbody/tr[3]/td[2]
```

同じ結果を得る事が出来た。
viの名前付きバッファを便利に使う



先日の「マークを便利に使う」
http://qiita.com/furu8ma/items/e0176b7fd49245c33f47

に引き続き本日は名前付きバッファを便利に使ってみます。


# なんども使う関数をバッファに入れておく

```vim
"[a-z]yy    カーソル行を名前付きバッファにヤンク(コピー)
"[a-z]dd    カーソル行を名前付きバッファにカット
"[a-z]p    カーソル業に名前付きバッファからペースト
```

範囲指定も便利ですが、とりあえず行の退避だけでも覚えると結構使えます。

ログデバック大好きな旧人類にとって、PHPのerror_log("")とかSwiftのprint("")とかを
特定の名前付きバッファに保存しておき、一発で呼び出せるようにしておくと便利です。
私の場合、"dにデバックログ系の関数を退避しておいて
ログ入れたいところに移動しておもむろに"dpします。

名前が付いているので通常のヤンクでは消えずずっと残っていてくれます。
キーボードだけで複数のクリップボードを扱えるイメージでとても便利。
最近はコードアシストが強力なので随分ありがたみが薄れてきましたが、それでも結構役に立ちます。


騙されたと思ってどうぞ。
fish shell用のパッケージマネージャーを作りました

## [fish shell](http://fishshell.com/)のカスタマイズ

最近zshから[fish shell](http://fishshell.com/)に移りました。デフォルトのセットアップがかなり優秀で、何もしなくてもわりと使えるのですが、結局ある程度カスタマイズがないと作業効率が下がるので、プラグインを管理するためのツールを探してみました。

oh-my-zshのfish版の[oh-my-fish](https://github.com/oh-my-fish/oh-my-fish)というのが存在していて、これを使うとパッケージを入れられるらしいですが、zshと違ってfishのセットアップは最初からほぼ完璧なので、パッケージ入れるためにわざわざフレームワークを入れるのはいかがものかと思って、結局自作をすることにしました。

## [Fundle](https://github.com/tuvistavie/fundle)の紹介

vimユーザがよく知っている[Vundle](https://github.com/VundleVim/Vundle.vim)を参考にして、[Fundle](https://github.com/tuvistavie/fundle)というパッケージマネージャーを作りました。

使い方としては、設定ファイルに

```
fundle plugin 'USER/REPOSITORY'

fundle init
```

を書くだけです。`fundle install`を走らせると、Githubからプラグインを取ってきてインストールしてくれます。
Githubにないものに関しては普通にgitのURLを入れれば使えます。

fishの場合は関数を追加したい時は`$fish_function_path`に入れると自動でロードされ、コンプリーションを`$fish_complete_path`に入れると自動でロードされるので、`fundle`で入ったプラグインに`functions`と`completions`というディレクトリがある場合はそのパスに追加するような仕様になっています。

[README](https://github.com/tuvistavie/fundle)に英語でもう少し詳しく書いてあります。
redux チュートリアルのtodoをやってみた

#redux チュートリアルのtodoをやってみた

[チュートリアルリンク](http://rackt.org/redux/docs/basics/)
[デモ](http://masatoyoshioka.github.io/redux_example/)
[ソース](https://github.com/MasatoYoshioka/redux_example)

```tree
|--app
|  |--actions.js
|  |--components
|  |  |--AddTodo.js
|  |  |--Footer.js
|  |  |--Todo.js
|  |  |--TodoList.js
|  |--containers
|  |  |--App.js
|  |--index.js
|  |--reducers.js
```

##やってみた感想
- チュートリアルがes2015で書かれていたのでbabelを使った
- とりあえずスムーズに書けた気がする

##次に
- reducerとは何か
- flexを勉強しなおす
Java8にもなったんだからFiles使おう

というだけの記事です。まだJava7から標準ライブラリに入った[java.nio.file.Files](https://docs.oracle.com/javase/jp/8/api/java/nio/file/Files.html)を知らない人向け。

昔

```java
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
```

今

```java
BufferedReader br = Files.newBufferedReader(path, StandardCharsets.UTF_8);
```
[Files#newBufferedReader(Path, Charset)](https://docs.oracle.com/javase/jp/8/api/java/nio/file/Files.html#newBufferedReader-java.nio.file.Path-java.nio.charset.Charset-)
[StandardCharsets#UTF_8](https://docs.oracle.com/javase/jp/8/api/java/nio/charset/StandardCharsets.html#UTF_8)

ちなみに今やCharsetは実行環境によらずデフォルトでUTF-8だそうですが、指定した方がいいと思います。StandardCharsetsがあるのでいちいち文字列定数で"UTF-8"と書いてtypoの危険性を孕む必要性はなくなりました。ただし、SJISことWindows-31JやEUC-JPは残念ながらありません。

ときどき欲しくなるファイルの全行読みも一発です。

```java
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
```
[Files#readAllLines(Path, Charset)](https://docs.oracle.com/javase/jp/8/api/java/nio/file/Files.html#readAllLines-java.nio.file.Path-java.nio.charset.Charset-)

ファイルサイズが想定できずメモリ負荷が危ぶまれるときはJava8から入ったlinesでStreamで処理できます。複雑なことをしないのなら、BufferedReaderで単調なreadLineループを書くよりこちらの方がいいでしょう。

```java
// この場合はCloseする必要があります。
try (Stream<String> stream = Files.lines(path, StandardCharsets.UTF_8)) {
    stream.forEach(line -> {
        // do something
    });
}
```
[Files#lines(Path, Charset)](https://docs.oracle.com/javase/jp/8/api/java/nio/file/Files.html#lines-java.nio.file.Path-java.nio.charset.Charset-)

引数がPathばかりですが、古いFileを使ったコードとの互換性も[File#toPath()](https://docs.oracle.com/javase/jp/8/docs/api/java/io/File.html#toPath--)を使って一瞬です。
互換性が必要ない場合は[Paths](https://docs.oracle.com/javase/jp/8/api/java/nio/file/Paths.html)で生成しましょう。

lines以外はJava7から存在していて、すでに登場から4年立っています。まだ知らなかった人はたまにはJavaDocを眺めるようにしましょう。

標準ライブラリが進化してくれるとOSSも自作ライブラリも使えないという暗黒中世めいた開発現場でもあんしんですね。えっ？まだJava5を使ってる？えっ？
Mac OS のアップグレード（クリーンインストール）

# 条件

- メイン機のアップグレード
- 安全第一、元に戻せる
- 主要なデータは NAS に保存、データ移行は無い
- iTunes フォルダは NAS にありマウントして利用

# 準備物
- インストーラ用 USB メモリ 16GB(8GB でも良い)
- 外付けハードディスク 512GB(メインディスク256GB の 2倍) or 同容量のディスクを２台

# 手順

## 事前準備
- USBメモリのラベルを installer に変更（後で上書きされるが，簡単にしておく）
- 外付けハードディスクを256GBづつに分割，ラベルを旧OS，新OS名にする(i.e. "ElCapitan", "highSierra")

## 概要
- 新OSインストール用 USB メモリを作成
- CCC で旧環境を外付けディスク１（パーティション１:ElCapitan）へバックアップ
- 外付けディスク１(パーティション１:ElCapitan）で起動、利用できることを確認
- 外付けディスク２（パーティション２:highSierra）へ新OSをクリーンインストール
- 必要な設定をすべて行い、常用できることを確認
- 旧OS固有情報の解除（後述）
- CCC で新OSを外付けディスク２（パーティション２:highSierra）から内蔵ディスクへコピー
- 内蔵ディスクで新OSを起動

# 固有情報の解除

## iTunes
- "アカウント" > "認証" > "このコンピュータの認証を解除

## iCloud
- "システム環境設定" > iCloud" > "サインアウト"

## iMessage
- "メッセージ" > 環境設定" > "アカウント" > "サインアウト"

## その他
- 動画サービス系サイトの認証情報の削除
- Bluetooth のペアリングの解除
セレクトボックスとラジオボタンは、一度選択するとHTMLのみではそれだけを解除できない。

# 結論

`<select>`、`<input type="radio">`は一度どれかを選択状態にすると、
HTMLだけではそこだけを何も選択していない状態に戻せない。

リセットボタンを使えば入力前に戻せるが、他の入力値も戻ってしまう。

`value=""`の選択肢は、必ずしも未選択とイコールではない。


JavaScriptを使えばもちろん解除できる。

# <i class="fa fa-code"></i> 動作

```html

<!DOCTYPE html> 

<html>
<body>
	<form action="">
	<select name="test1" id="">
		<option value="1">1</option>
		<option value="2">2</option>
		<option value="3">3</option>
	</select>
	<input type="submit">
	</form>

	<form action="">
	<select name="test2" id="" size="5">
		<option value="1">1</option>
		<option value="2">2</option>
		<option value="3">3</option>
		<option value="">なし</option>
	</select>
	<input type="submit">
	</form>
	
	<form action="">
	<input type="radio" name="test3" value='A'>
	<input type="radio" name="test3" value='B'>
	<input type="radio" name="test3" value=''>
	<input type="submit">
	</form>
</body>
</html>

```

をサーバーに置いたり、
[タグテスト - HTMLタグを入力してブラウザ表示チェック/ホームページマスター]
に貼り付けたりしてパラメーターチェック

一度選択すると、初期状態の未選択状態には戻せない。

何も選択しないでsubmitすると、パラメーターは付加されないが、`value=''`を選択すると空文字が付加される。
`required`属性的には`value=''`は未選択とみなされるが、クエリ的にはちょっと違うように見受けられる。

なお、`<select>`はそのままだとドロップボックスになり最初の項目が選択されているが、`size`を指定するとリストボックスになり、未選択状態を作れる。

[タグテスト - HTMLタグを入力してブラウザ表示チェック/ホームページマスター]: http://hmaster.net/tagtest.html

# <i class="fa fa-cubes"></i> 調べるきっかけ

フォームをカスタマイズできる所で、必須でないリストやラジオボタンを追加した時、
必須でないので未選択で登録したいときに、誤って選択してしまって戻せなくて泣いた。
リセットボタンも無いし(あっても使わないけど)、更新しても当然選択されたままだしで、
結局他のテキストエリアの入力値などはコピペで退避し、ページを開き直し、
他のラジオボタンなどは選択しなおしてとほぼ全やり直しが必要になってしまった。

ではと`value=""`の項目も追加したが、
これも当然ですが、未選択ではなく`value=""`を選択したものとみなされて登録されてしまった。

***

他にも、リストの複数選択の上限を決められないなど、HTMLのみではビミョーに手が届かない…
generator と promise を使って、mapSeries を自作

### 概要

nodejs v4.2 LTS が出たので、generators の勉強を兼ねて mapSeries を async モジュールを使わず generators で自作してみたという話。

### 使用モジュール等

- `node`: v4.2.2
- `co`: v4.6.0

`co.wrap` を利用することで思ったよりも簡単に出来ました。

### while で作成した mapSeries

```js
/**
 * @param {Array} array
 * @param {Function} iteratee
 * @param {Object} thisArg
 * @return {Promise}
 */
const co = require('co');
const mapSeries = co.wrap(function *(array, iteratee, thisArg){
  const length = array.length;
  const fn = thisArg ? iteratee.bind(thisArg) : iteratee;
  let i = 0;
  let result = Array(length);

  while(i < length){
    result[i] = yield Promise.resolve(fn(array[i]));
    i++;
  }
  return result;
});
```

### for-of で作成した mapSeries

こっちの方がすっきりしているように思えます。

```js

/**
 * @param {Array} array
 * @param {Function} iteratee
 * @param {Object} thisArg
 * @return {Promise}
 */
const co = require('co');
const mapSeries = co.wrap(function *(array, iteratee, thisArg){
  const fn = thisArg ? iteratee.bind(thisArg) : iteratee;
  let result = [];

  for(let item of array){
    item = yield Promise.resolve(fn(item));
    result.push(item);
  }
  return result;
});
```

### 実行結果

```js:node-repl
> const arr = [ 123, 456, 789 ]; 
> const fn = (item) => { 
  return new Promise((resolve, reject) => { 
    setTimeout(() => { 
      console.log('sync: ', item); 
      return resolve(item); 
    }, 1000 - item); 
  }); 
}; 

> mapSeries(arr, fn).then(console.log);
Promise { <pending> }
> sync:  123
sync:  456
sync:  789
[ 123, 456, 789 ]
```

並列で実行ならログは、 789 → 456 → 123 出るはず。順番に出てるのでうまく行っているっぽいです。
for-of の mapSeries でも同じ結果。
async モジュールを使う以外で、何か他に良い方法があったら教えてください。
絶対パスを使ってしまって、テストディレクトリをドキュメントルートにしたい場合でajax（非同期）があった場合の処理

タイトル通りの事があった場合、すべてのパスをテスト環境用に調整するのは非常にめんどうです。
そこで、よくあるのが「mod_rewrite」を使用した下記の用な処理です。

**loginへのページを転送したい場合**
/login/に下記のhtaccessを設置（sample以下じゃないから注意してね）

```htaccess:/login/.htaccess
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^http://connan.jp/login/(.*)$
RewriteRule ^(.*)$ /sample/login/$1 [R]
```

で、ヘッダーなどに非同期でログイン処理が実装されている場合、これではなんか変なことになる（ページが真っ白になったり、scriptタグしかでなかったり）ので、ajax通信の時は転送しないようにします。

```htaccess:/login/.htaccess
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^http://connan.jp/login/(.*)$
RewriteCond %{HTTP:X-Requested-With} !=XMLHttpRequest # ここを追加
RewriteRule ^(.*)$ /sample/login/$1 [R]
```

ひとまずこんな感じで対応できます。
FFMPEG（FFMBC）でＸＤＣＡＭ形式のＭＸＦファイルを作る。

decklinkを使えるようにしてＦＦＭＰＥＧをビルドしたので
キャプチャーをします

ただキャプチャーするのであればこんなに長くなくてもいいですが・・

ffmpeg -bm_v210 1 -f decklink -i "DeckLink SDI 4K@9" -timecode "00:59:56;00" -timestamp now -colorspace bt709 -color_trc bt709 -color_primaries bt709 -map 0:1 -flags +ildct+ilme -top 1 -vcodec mpeg2video -pix_fmt yuv422p -aspect 16:9 -b:v 50000k -maxrate 50000k -minrate 50000k -map 0:0 -ac 8 -acodec pcm_s24le -ab 24k -ar 48000 -s 1920x1080 -r 30000/1001 -t $2 -y $1.mxf

最初の-bm v210 1で10ビットで取り込みを行います

-i "DeckLink SDI 4K@9"は、入れているボードと入力信号で決まります。

入れているボードのチェックは

ffmpeg -f decklink -list_devices 1 -i dummyでデバイスの名前が出ます。

出てきたデバイス名（当方の環境ではDecklink SDI 4K）を-iの後にセット

ffmpeg -f decklink -list_formats 1 -i 'Decklink SDI 4K'

番号と、フォーマットのリストがでるので入力している信号にあったものを@以下につけます

XDCAM形式はカラースペースがbt709らしいのでとりあえずセット

-colorspace bt709 -color_trc bt709 -color_primaries bt709

ビットレートやピクセルフォーマットも同様に仕様に合わせてセット

※ＸＤＣＡＭは音声は、１ストリーム１モノらしいので本当はこの段階で
　映像を含めて９ストリーム作りたかったけど、うまく出来ませんでした

このままだと、再生出来ない機器があったのでＦＦＭＢＣでさらに変換と
音声のストリーム分け、ファイル切り出しを行います

ffmbc -ss $3 -i $1.mxf -threads 7 -target xdcamhd422 -tff -timecode "00:59:56;00" -acodec pcm_s24le -flags +ildct+ilme -map_audio_channel 0.1.0:0.1 -map_audio_channel 0.1.1:0.2 -map_audio_channel 0.1.2:0.3 -map_audio_channel 0.1.3:0.4 -map_audio_channel 0.1.4:0.5 -map_audio_channel 0.1.5:0.6 -map_audio_channel 0.1.6:0.7 -map_audio_channel 0.1.7:0.8 -t $4 $2.mxf -acodec pcm_s24le -newaudio -acodec pcm_s24le -newaudio -acodec pcm_s24le -newaudio -acodec pcm_s24le -newaudio -acodec pcm_s24le -newaudio -acodec pcm_s24le -newaudio -acodec pcm_s24le -newaudio -acodec pcm_s24le


８コアのＸＥＯＮプロセッサーを使っているのでスレッドを７でやってみました
FFMPEGからは-threadsのオプション消えているみたいです

※出来たファイルはソニー機器では読めません。どうもＮＲＴメタというメタ情報が
　無いと不明ファイルとして扱ってしまうようです。

再生確認機器
　・さくら映機　Prunusユニバーサルプレーヤー
　　　これはＦＦＭＢＣで変換しなくても大丈夫だった
　
　・朋栄　ＭＢＰ１０００

　・東芝　ＶＩＤＥＯＳneo
Rspec: mock と double の違い

違いはない。(たぶん)

mock メソッドは非推奨なので、替わりに double を使うこと。

```rb
- mock(name: 'Jack')
+ double(name: 'Jack')
```

---

`DEPRECATION: mock is deprecated. Use double instead.`

# 環境

- rspec-rails 2.14.1



<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# メンター受付


https://menta.work/user/5694

<!-- Update From Qiita API -->
VS2015でSwift2.0入門　③基本文法続きと、SwiftでLINQ

# 序.
MSのVisualStudio2015でSwift2.0もどき(RemObjects Silver)を実行してみる、その３。
[前回](http://qiita.com/kmry2045/items/1261e3c9182bf2cfc958)までで、RemObjects Silverが、うたい文句通り、Swift2.0準拠といえることはわかったので、
今回は軽く文法の確認。クロージャを扱うついでに、.NETのLinqも使ってみる。

**注、Swift未経験の人で概説が必要な時は適宜この記事あたりをチラ見のこと : [Swift文法メモ](http://codezine.jp/article/detail/7842) **
*# Swuft1.x時代のものなので、現行バージョンでは動かないコードもあるかもだが、参考にはなる*

#1. if文、三項演算子、クロージャ

いずれも基本的なところは動作した。

```Program.swift
import System.Collections.Generic
import System.Linq
import System.Text
import System.Threading.Tasks

println("Console App:")


let str = "h e l l o w o r l d"
var spcs=""
for c in str{
    if c != " " {println(spcs+c)} else {spcs += c} //if文
} 
println(" => if文の例\n")

spcs=""
for c in str{
    spcs += (c == " ") ? "○" : "" //三項演算子
    print(spcs+c)
} 
println(" => 三項演算子の例\n")

let arr = split(str) {a in a == " "} //　{ }部分がクロージャ
for a in arr {println(a)}
println(" => クロージャの例")

Console.ReadLine()

```
if文はgolangっぽいね、三項演算子はCっぽいが、予想の範囲内。

Swiftのクロージャは、いろいろな書き方が用意されている。
上の例では、split関数が行う文字列分割操作の内容を{$0 == " "}というクロージャで定義している*(要するに空白文字で文字列を分割して、配列を得る)*。

以下に実行結果を引用する。
![win10_swift_3.PNG](https://qiita-image-store.s3.amazonaws.com/0/16455/e2dff5f6-7327-f43c-31de-4f005c279099.png)


クロージャに慣れるまでは、基本的なところを、[Swift のクロージャが面白い](http://qiita.com/uasi/items/0a72bb444002471d832f)を参考にさせてもらったりして書くと良い。
F#やhaskellやscalaなどの（純粋・不純問わず）関数型言語を使ったことがある人は簡潔な略記法でどんどん書けばよいだろう。

私が気に入った書き方は以下:

> let arr = split(str) {$0 == " "} //　{ }部分がクロージャ


#2. Swiftクロージャ渡しで、LINQ

さて、C#で関数型テイストといえば、Linq。
RemObjects Silverの.NET実行環境では、ディフォルトでLinqがインポートされている。
> import System.Linq

Swift界隈からの人は、何それ状態と思うので、[Modern C# 入門の備忘録 - Linq入門編](http://qiita.com/acple@github/items/e77bc70d8eeeec3939f8)をチラ見しておこう。
例えば、SomethingsというInt型のコレクションがあるとする。
Somethingsの各要素のうち10以上のものを取り出して、取り出したものを二乗する操作をLinqでは以下のように書く。

```
//C#の例

 Somethings.Where(x => x > 10).Select(x => x * x)
```
()で囲まれた部分は無名関数。これって、Swiftのクロージャ...なんです、たぶん。

SwiftでLinqを書いてみる:


```.swift
let arr2 =　1...20 　　　　　　　　　　　　　　　　　　//配列を得る
let arr3 = arr2.Where {$0 > 5} .Select{$0 * $0} 　　//  Linq:Where&Select
for a in arr3 {print(a+":")} 　　　　　　　　　　　　//(a+":"の部分は暗黙の型変換
```

実行結果:

![win10_swift_4.PNG](https://qiita-image-store.s3.amazonaws.com/0/16455/1d98b0e2-713d-9d80-52eb-04ed7533e0d6.png)

C#でLinqの事例は各所に転がっているので、そちらを参考にいろいろと書いてみるとよいだろう。
例:
http://yohshiy.blog.fc2.com/blog-entry-274.html

*#Swiftのテイスト的にはF#の事例も参考になりそう。*

# 3. .NET上でLinqを使う意義。
.NET&JVM上のSwift互換環境RemObjects Silverでは、当座、iOS上のSwiftライブラリをそのまま持ってくることは難しそう。.NET環境上ではLinqを使うことで、コレクションの操作などがかなり楽になるのが最大の意義。
また、SwiftからC#ライブラリの呼出方などのマスターにもつながっていくとも期待できる(そのために、近いうちに、C#のdelegateとSwiftのdelegateを比べることとしたい)。

VS2015上で動くRemObjects Silverでは、JVMよりも.NET上でのSwift実行がしっかりとできそうなイメージ。今後は、(自分は使ったことがないのだが、)xamarinのような、クロスプラットフォーム開発環境として進化していくのかもしれない。自分が狙うところは、もう少しRemObjects Silverに慣れた後に書くこととしたい。
【MT】便利なMovableTypeプラグイン一覧

公式に毎年12月に人気プラグインの投票があります。
そこにランクインするプラグインは、有用なものばかりですので、そちらもご覧ください。

+ [Movable Type プラデミー賞 2014 発表！](http://www.movabletype.jp/blog/pludemy-goes-to.html)
+ [Movable Type プラデミー賞 2015 発表！](http://www.movabletype.jp/blog/2015-pludemy-goes-to.html)

2015-12-28 上記追記

--------------------------

ここに記載しているプラグインのライセンス、対応バージョンは配布サイトで確認してください。
リンク先が最新バージョンではない可能性があります。
最新バージョンがないかググッてください。

他に便利なプラグインを発見したら追加します。

|プラグイン名|用途|
|:--|:--|
|[MultiBlogExt](http://tec.toi-planning.net/mt-column/plugin/multiblogext/)|ブログ記事の削除時に再構築|
|[QuickRebuild](http://tec.toi-planning.net/mt/quickrebuild/)|全てのブログを一括で再構築|
|[PageBute](http://www.mtcms.jp/movabletype-blog/plugins/pagebute/)|ページを分割してページャーを追加|
|[IndexRebuilder](http://www.skyarc.co.jp/engineerblog/entry/movabletypeindexrebuilder2.html)|インデックステンプレートを自動で再構築|
|[UploadDir](http://labs.m-logic.jp/cat2/uploaddir/)|拡張子に応じてアイテムのアップロード先（パス）を自動で入力|
|[MultiBlogExt2](https://www.anothersky.pw/skyward/archives/000168.html)|非公開（公開終了）になったときに再構築|
|[NumericCustomFields](http://www.h-fj.com/blog/archives/2009/02/21-145227.php)|数値型のカスタムフィールドを追加するプラグイン|
|[CharsetEncoder](http://www.koikikukan.com/archives/2010/05/25-015555.php)|指定した文字エンコーディング（文字コード）のページを出力する|
concrete5でワークフロー


concrete5にて編集者がページ編集し、管理者が承認するワークフローを試してみました。
※多々間違いがあるかもしれません……

## 編集者グループの追加
管理画面　→　メンバー　→　ユーザーグループ　→　グループを追加
![Kobito.pn938r.png](https://qiita-image-store.s3.amazonaws.com/0/92593/ee60b3ef-dfb8-252a-a615-51ee47fb2d40.png "Kobito.pn938r.png")

## 編集者ユーザの追加
管理画面　→　メンバー　→　ユーザー検索　→　ユーザーを追加

+ 先ほど作成した「編集者」グループにチェック

![Kobito.ujq1Dv.png](https://qiita-image-store.s3.amazonaws.com/0/92593/bce8b1ce-282e-a918-bd0e-b9ef53a6d46c.png "Kobito.ujq1Dv.png")

## 編集者権限の追加
### 管理画面の表示権限追加
管理画面　→　サイトマップ　→　フルサイトマップ
1. 「サイトマップにシステムページを含める」にチェック
2. サイトマップの「管理画面」をクリック
3. メニューの「権限」をクリック
4. 「表示」権限をクリック
5. 新規（含む）　→　選択　→　グループ　→　編集者　→　保存　→　保存　→　変更を保存

### サイトマップのページ表示権限追加
1. サイトマップの「ホーム」をクリック
2. メニューの「権限」をクリック
3. 「サイトマップでページを表示」権限をクリック
4. 新規（含む）　→　選択　→　グループ　→　編集者　→　保存　→　保存　→　変更を保存

### コンテンツの編集権限追加
1. サイトマップの「ホーム」をクリック
2. メニューの「権限」をクリック
3. 「コンテンツを編集」権限をクリック
4. 新規（含む）　→　選択　→　グループ　→　編集者　→　保存　→　保存　→　変更を保存

### サイトマップのアクセス権限追加
管理画面　→　システムと設定　→　権限とアクセス　→　タスク権限
1. 「サイトマップへのアクセス」権限をクリック
2. 新規（含む）　→　選択　→　グループ　→　編集者　→　保存　→　保存　→　保存

## ワークフロー作成
管理画面　→　ワークフロー　→　ワークフロー一覧　→　ワークフローを追加
1. ワークフロー名を入力し、「新規」クリック
2. 詳細を編集
3. 下記の通り、各ワークフローに管理者グループ、編集者グループを設定し保存
![Kobito.ipuZPD.png](https://qiita-image-store.s3.amazonaws.com/0/92593/1111c979-91e1-c64b-0a72-cc15a6d68677.png "Kobito.ipuZPD.png")

## ワークフロー設定
管理画面　→　サイトマップ　→　フルサイトマップ
1. サイトマップの「ホーム」をクリック
2. メニューの「権限」をクリック
3. 「変更を承認」権限をクリック
4. 「アクセス」タブ　→　新規（含む）　→　選択　→　グループ　→　編集者　→　保存
5. 「ワークフロー」タブ　→　先ほど作成したワークフローにチェック　→　保存　→　変更を保存

# 以上でワークフローの設定は完了


## ワークフローを試してみる
1. 編集者でログイン
2. 任意のページを編集、保存
3. 編集モードを終了
4. 「ワークフローに送信」をクリック

![Kobito.HyogtY.png](https://qiita-image-store.s3.amazonaws.com/0/92593/c4f239d5-7264-a08e-8932-f4f72e52dc6d.png "Kobito.HyogtY.png")

ワークフローの「エントリーの通知」で管理者グループを設定していたので、承認要求メールが管理者に届きます。
ワークフローの「承認か拒否」で管理者グループを設定していたので、承認もしくは拒否するために管理者でログインし直します。

5. 管理者でログイン
6. 管理画面　→　ワークフロー　→　確認待ち
7. 承認要求を「キャンセル」または「ページを承認」にて処理

![Kobito.MlhY0e.png](https://qiita-image-store.s3.amazonaws.com/0/92593/505a8c95-39b4-9f69-6761-91d27ebc7d59.png "Kobito.MlhY0e.png")

「キャンセル」すればワークフローの「拒否通知」に設定されてるユーザに通知
「ページを承認」すればワークフローの「承認を通知」に設定されてるユーザに通知

## はまりポイント
最初はグループセットというものを使ってワークフローに設定していましたが、ある条件にて下記エラーが出ます。

PHP Fatal error:  Class 'Concrete\Core\Permission\Access\Entity\UserInfo' not found in /var/www/html/concrete/src/Permission/Access/Entity/GroupSetEntity.php on line 57

どうやら管理者のadminユーザを管理者グループに追加し、グループセットに管理者グループを設定、そのグループセットをワークフローに設定するとエラーになるようです。
これでだいぶはまった……

## 参考サイト
[サイトマップのアクセス権](http://www.generation.ne.jp/topics/accesstositemap/)
[concrete5でユーザーに権限を付与するまでの作業一例](http://exp-box.net/140/)
Swift「Expression was too complex to be solved in reasonable time; consider breaking up the expression into distinct sub-expressions」が出た時の対処

Swiftでコードを書いていたら、こんなエラーが出て、コンパイルできない。。。

```
Expression was too complex to be solved in reasonable time; consider breaking up the expression into distinct sub-expressions
```

該当の箇所はこんな感じ。
※計算式は適当ですが…

```
let x : CGFloat = CGFloat((320 / 4 - 140 / 2) + (15 * (i % 2)) + (320 * (i % 2)))
```

これ、()が多いって言われているんですね。
なので、もっとわかりやすく書き換えなさいっていうお達し。

なので、こうしたら、コンパイルできました。

```
let x =(320 / 4 - 140 / 2)
let y =(15 * (i % 2))
let z = (320 * (i % 2))
let xyz : CGFloat = CGFloat(x + y + z)
```

複雑なのはよくないってことなんでしょうね。
ということで、分割して解決。


参考：http://stackoverflow.com/questions/25569373/swift-compound-arithmetic-operation-error
書籍「構造化分析とシステム仕様」

◆学習対象
書籍名 構造化分析とシステム仕様: 目指すシステムを明確にするモデル化技法
著者 トム・デマルコ
出版社 日経BP社, 1994
ページ数 400 ページ
![h_906700.gif](https://qiita-image-store.s3.amazonaws.com/0/100247/75e89210-f938-9418-8758-a4aed56a0a65.gif)

◆内容紹介（日経BP書店HP 引用）

~~~
システム・アナリストが求める構造化分析をその第一人者がその概念と運用を書き下ろしました。
基本概念の解説はもちろん、構造化分析の主流をなす「データフロー・ダイアグラム」について、概念、規則、命名、書き方、データ階層化、評価、改良までを詳述しています。
さらにデータ・ディクショナリの定義と構築、プロセス仕様による構造化分析と発展します。
まとめではシステムのモデル化を具体例を交えながら、論理モデル、物理モデルの構築、メンテナンス、評価などまで丁寧に解説します。システム・アナリストには必読の書と言えます。
~~~

#１．構造化分析
　構造化分析(Structured Analysis)は、トム・デマルコによって考案され、1970 年代後半から普及した要求を階層的に設計していく分析手法。以下のようなツールを使って新しいドキュメントを作成する場合に用いられる。
　　- データフロー・ダイヤグラム
　　- データ・ディクショナリ
　　- 構造化言語
　　- デシジョン・テーブル
　　- デシジョン・ツリー

###▽ 分析の目的とその利点
　分析の最優先課題は成功を勝ち取ることでははなく、失敗を回避すること。
　この分析に構造化を取り入れることで一次元的なモノの考え方ではなない、
　**多次元的なアプローチから重大なエラー発生確率を極小化する**ことができる

~~~

業務の中における具体例

＜ユーザ（顧客）＞
・開発対象の機能をアナリストに適切に伝達する
・開発状況に合わせて、システム目標の修正や修正できるような体制を整える
・成果物（システム）の運用を正しく認知する

＜アナリスト（開発者）＞
・ユーザの要望を実現する手段を呈示する
・開発状況を明確にユーザへ伝達し、目標達成に向けて随時改修を行う
・成果物に関してドキュメントを作成し、運用を正しく行えるよう体裁を整える

アナリストは複数のシステム計画案について、予算と効果を分析し、関係者にフィードバックすることによって最適目標を選定する必要がある。こうした場面で構造化分析が応用できれば、システムの全体像を掌握しやすくするだけでなく、費用と効果の見積もり精度を向上させ、同時に顧客・開発者間のヒューマンエラーを最小限に抑えることが出来る。
~~~

###▽分析の欠点
業務の中で発生する様々な失敗や問題は、その問題箇所を分析することで解決したり打開策を講じることに繋がる。
しかし注意すべき点は、例え膨大な時間を分析フェーズに講じたとして、
**必ずしも解決できるという訳ではない**ことを念頭に置く必要がある。

~~~
(e.x.)
1、コミュニケーションの問題
2、システム要求の変更
3、ツールの欠如
4、ドキュメントの問題
5、仕事の分担の問題
6、政治的な配慮
~~~
Mac で Ruby の標準入力が受け取れないと思ったらvimrcに要らんもん書いてたせいだった

最近 Ubuntu から Mac に環境移行して，Ubuntuとかirb上では当然使える `gets` が何故かMac のターミナル上でだけ使えないということがありました．
これに対して，__「Ruby Mac 標準入力 使えない」__ とか __「Mac Ruby gets doesn't work」__ とか __IQ低そうなキーワード__ でググってたのですが，まったくヒットせず，それもそのはず，Mac は全く関係なくてvimrcというか改行コードのせいなのでした．
こんな事態になる場合は滅多にないと思いますが，同じような症状でググって途方に暮れる人がいないとも限らないので一応書き留めておきます．

## 状況

Ruby で標準入力を一行受け取って，その文字を出力するコードは以下のようになります．

```test.rb
str = gets.chomp
puts str
```

なので，このプログラムを実行した時の結果は，以下になることが期待されます．

```bash
$ ruby test.rb                                                                                                                                 
hogehoge
hogehoge
$ 
```

ただ，自分の環境では，getsの内容がstrに代入されず，以下のようになっていました．

```bash
$ ruby test.rb                                                                                                                                 
hogehoge

$ 
```

## 原因と解決策

結論からいうと，ソースコードの改行コードが __¥r__ になっていたのが原因で，__¥n__ に置換したら解決しました．

| システム | 改行コード |
|---|---|
| Unix | LF(¥n) |
| Mac (OS X以前) | CR(¥r) |
| Windows | CR+LF(¥r¥n) |

なんでそんなことになってたかというと，vimrc に昔わけも分からず書いた行が混じっていたからでした．

```vim
" set fileformats=mac,unix,dos
```

コメントアウトして解決．

## なぜ Ruby のソースコードの改行コードの違いで問題が起きるのか

わからないのでもし分かる方いらっしゃったら教えて下さい．
以下のような Python のコードは，改行コードが ¥r であっても，ターミナル上で正常に動きます．

```test.py
-*- coding: utf-8 -*-
s = raw_input()
print s
```

## 教訓

.vimrc にわけも分からずごちゃごちゃ書くのはやめよう
findコマンドのmtimeオプションまとめ


---

findコマンドの時間指定は色々パターンがあるので、
まとまてみました。

---

時間指定オプション一覧。

| オプション|概要|
|:-----------|:------------|
| -mmin|ファイルのデータが最後に修正された日時（分指定）|
| -mtime|ファイルのデータが最後に修正された日時（日指定）|
| -amin|ファイルのデータに最後にアクセスされた日時（分指定）|
| -atime|ファイルのデータに最後にアクセスされた日時（日指定）|
| -cmin|ファイルのデータとステータスが最後に修正された日時（分指定）|
| -ctime|ファイルのデータとステータスが最後に修正された日時（日指定）|

## 現在から3日前まで（現在時間〜72時間前）
```
# find ./ -mtime -3
```

## 3日前（72時間前〜96時間前）
```
# find ./ -mtime 3
```

## 過去から3日前まで（72時間前〜過去）
```
# find ./ -mtime +2
``` 
※ (2+1)日前以降

---

<b>daystart</b>オプションを指定すると0時を基準にします。
1日単位で範囲指定したい場合に使用します。

例として、現在を12月24日03時00分とします。

## 現在から3日前まで（12月24日24時00分〜72時間前）

```
# find ./ -daystart -mtime -3
```

## 3日前（12月21日24時00分〜24時間前）

```
# find ./ -daystart -mtime 3
```

## 過去から3日前まで（12月21日24時00分〜過去）

```
# find ./ -daystart -mtime +2
```
※ (2+1)日前以降

---

少数指定も出来るみたいです。

## 12時間前まで（現在時間〜12時間前）
```
# find ./ -mtime -0.5
```

---
docker 1.9 以降(?)で centos6 image 起動する

boot2docker の代わりに docker toolbox が出たのでシャシャって入れたら手元の Dockerfile でつくった centos6 ベースの image がのきなみ起動しなくなった。

/etc/rc.d/rc.sysinit の中の fsck で

    fsck.ext4: Unable to resolve 'UUID=78890fee-d60d-46c8-b8e9-68a9b0bc4159'

とかなってるからだった。


@woremacx さんに「fsck 起動止めれば」とアドバイスを貰って rc.sysinit で fsck 呼ばないようにしたら起動した。

✧＼\ ٩( 'ω' )و /／✧
JAVA GUI(Graphical User Interface


■Test18.java

```java
import java.awt.FlowLayout;

import javax.swing.*;

public class Test18 {
	public static void main(String[] args) {
		JFrame frame = new JFrame("はじめてのGUI");
		JLabel label = new JLabel("Hello World!!");
		JButton button = new JButton("押してね");
		frame.getContentPane().setLayout(new FlowLayout());
		frame.getContentPane().add(label);
		frame.getContentPane().add(button);
        // setDefaultCloseOperation()→ユーザーがこのフレームで「クローズ」を開始した時に実行される処理を返す
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(300, 100);
        // ウィンドウを表示する
		frame.setVisible(true);
	}

}
```

■実行結果
![testgui.png](https://qiita-image-store.s3.amazonaws.com/0/95187/250ef29b-1d2e-b862-ca58-1314b67ba5d6.png)

ContentPaneとは、JFrameの表示領域です。

　JFrameに表示したいコンポーネントは、ContentPaneに追加する必要があります。

一番右の「×」ボタンを押した時にどのような処理を行うのかを設定します。設定を行うにはJFrameクラスで定義されているsetDefaultCloseOperationメソッドを使います。
瑕疵担保責任に関する商法を調べてみた

## はじめに
[瑕疵担保責任に関する民法を調べてみた](http://qiita.com/syou007/items/eed3690ec082f97dc0ac)を調べた時に、請負業務は主に商人と行う場合が多いので商法が適用される事を知った。

なので、今回は商法について調べて見る。

## 商法第526条
1. 商人間の売買において、買主は、その売買の目的物を受領したときは、遅滞なく、その物を検査しなければならない。
2. 前項に規定する場合において、買主は、同項の規定による検査により売買の目的物に瑕疵があること又はその数量に不足があることを発見したときは、直ちに売主に対してその旨の通知を発しなければ、その瑕疵又は数量の不足を理由として契約の解除又は代金減額若しくは損害賠償の請求をすることができない。売買の目的物に直ちに発見することのできない瑕疵がある場合において、買主が六箇月以内にその瑕疵を発見したときも、同様とする。
3. 前項の規定は、売主がその瑕疵又は数量の不足につき悪意であった場合には、適用しない。

商法で瑕疵担保責任に関して記載されている条文は上記のみだ他と思います。
あとは民法が適用されるかと思います。

1項を見ると、買った人に検査義務がある事が書かれてます。
これは請負業務で言う`受け入れ試験`を指しています。
`受け入れ試験`はお客さんが行うと言うのはその通りですが、法律で決まっている事を初めて知りました。

2項を見ると`バグ`を発見した場合は売主に対して直ちに通知する必要があると書かれている。
この通知をしないで`契約の解除又は代金減額若しくは損害賠償の請求をすることができない`と書かれているので、まずは通知義務が発生する。
ここでのポイントは`直ちに`というところで「数ヶ月前に発見してたんですけど」となると、`直ちに`の部分が守られていないため通知義務違反のような形になる。

また、期間については「六箇月以内」と書かれているがここの解釈は難しい。
文字通り解釈するなら通知は「六箇月以内」までという事になる。
ただしここには瑕疵担保責任に関しては書かれていないため、六ヶ月以内に通知されたものは瑕疵担保請求権の行使ができる。
すなわち、六ヶ月以内に見つかったものはその後１年以内までは瑕疵担保として対応しなければならない。

3項に当たるような事はなかなか無いと思うが、簡単に言えば売主が`バグ`を認識した上で売った場合は無効になるという事だ。
ただ、これを立証するためには証拠が必要となるため難しいだろう。

## 商法第522条
1. 商行為によって生じた債権は、この法律に別段の定めがある場合を除き、五年間行使しないときは、時効によって消滅する。ただし、他の法令に五年間より短い時効期間の定めがあるときは、その定めるところによる。

という条文も見つけたが、、、`商法第526条`と`民法第637条`に期間が書かれているため適用されるケースは無いのでは無いだろうか・・・。
それとも契約書があっても５年以上の瑕疵担保は認め無いという事だろうか・・・。
`五年間行使しないとき`と書かれているので、このように解釈するのは難しい。

一体いつ使うのだろうか・・・。

## 参考
[契約書の読みかた（4）瑕疵担保とは](http://j-net21.smrj.go.jp/well/law/column/4_15.html)
Qiita > 要望 > URLリンクのMarkdown自動生成機能

```txt:動作環境
Qiita(web)
```

## Qiitaに欲しい機能。

- URL自動Markdown記述機能

## 使い方

1. URLをドラッグ
    ![qiita1.png](https://qiita-image-store.s3.amazonaws.com/0/32870/f428a17b-6dd9-3f17-5991-7fba59bebc38.png)

1. 編集部分にドロップ

    ![qitia2.png](https://qiita-image-store.s3.amazonaws.com/0/32870/68f2a5e3-991b-e1eb-cf8e-ac6abf988c19.png)


1. 結果として以下のようになるのが希望。

   ![qiita3.png](https://qiita-image-store.s3.amazonaws.com/0/32870/831cc774-8059-dc53-40bf-eb528486c430.png)


## 備考

画像をドロップする機能を似せて実装できないだろうか。

この機能があれば編集がしやすくなる。
sublime text3  個人設定 2015

# sublime text3 設定メモ

備忘録として。

##Setting - user

```
{
	"color_scheme": "Packages/User/SublimeLinter/Monokai (SL).tmTheme",
	"default_line_ending": "unix",// 新規ファイルの文字コード
	"draw_white_space": "all",// スペースとタブを可視化
	"file_history_retention": 30,// 履歴を残す日数
	"fold_buttons": true,// 折りたたみボタンの表示
	"font_size": 10,
	"ignored_packages":
	[
		"Vintage"
	],
	"open_files_in_new_window": true,
	"show_encoding": true,// エンコーディングを表示
	"show_line_endings": true,// 改行コードを表示
	"tab_size": 2,// タブのサイズ
	"trailing_spaces_regexp": "　|[ t]+",// 全角スペースを警告
	"translate_tabs_to_spaces": true,// タブ文字をスペースに変換
	"trim_trailing_white_space_on_save": true,// ファイル保存の度に行末の不要スペースとタブの自動削除する
	"word_wrap": true// テキストを折り返す
}
```

## Package Settings

- Bracket Highlighter //カッコ類を強調
- Local History
- Package Control
- PHP Code Sniffer
- Side Bar
- Tag
- Trailing Spaces
- ConvertToUTF8
- SublimeLinter

### 導入しよう
- DocBlockr
- Abacus
- GitGutter
- Origami
- SyncedSideBar
Dropbox Business で Public フォルダが使えない問題の解決策

# はじめに
Dropbox で 1GB のファイルを A さんと B さんで共有すると、A, B の両方のアカウントで 1GB がカウントされ、両方のアカウントで残り容量が 1GB 減ります。ファイルを共有した場合には重複してカウントする仕様にしないと、無料アカウントをたくさん作って無料で容量を増やし放題になるのでこの仕様は確かに仕方が無いと思います。

ところが最近、Dropbox で共有する大きめのファイルが増えてきました。大きいファイルを共有すると容量制限が厳しくなってきます。Dropbox Business を契約するとチーム内で共有しているファイルが１回しかカウントされないので、上の例だと A, B さんが同じチームに居れば別々の契約より 1GB だけ余計に容量が使えることになります。

# Dropbox Business を申し込んだが・・・
そこで、Dropbox Business の無料トライアルを申し込んでみたのですが Dropbox Pro の時には使えていた、Public フォルダーで公開していた Web ページが全滅してしまいました。設定が変わったのだと思い、設定を見直したのですが直し方もよく分かりませんでした。

色々と試行錯誤をしている間に直すことができましたが、かなり面倒だったので記事を書いて備忘録を書こうと思った次第です。

# なぜ直し方が難しいのか？（推測）
Dropbox は Public フォルダを廃止したがっている気がします。Public フォルダまわりの設定項目は基本的に設定メニューの表には出てこないように設計されており、「ヘルプ」から Public フォルダの使い方や問題について検索すると、検索して出てきた記事に設定メニューへのリンクが張ってあり、こっそり設定できる、という仕組みになっていました。

# 具体的にどうすれば良いのか
チーム全体の設定として「Public フォルダを有効にすることを許す」設定を行い、個々のアカウントで「Public フォルダを有効にする」設定を行うと従来通りに Public フォルダを使用することができました。

まずは前者の全体設定です。[Dropbox Business チーム メンバーの Public フォルダをオフまたはオンにする方法](https://www.dropbox.com/help/4224?path=dropbox_for_business)のページで解説されている[Public フォルダを有効または無効にする](http://dropbox.com/team/admin/public_folders)をクリックし、チーム全体で Public フォルダを使用する設定をできるようにします。設定が上手くいくと下記のような表示になるはずです。

![image](https://qiita-image-store.s3.amazonaws.com/0/592/95c5722c-6037-7f46-93d2-601f5988347f.png)

次に、個々のアカウントで Public フォルダを有効にします。この作業は Public フォルダがもともと有効なアカウントを使っていた場合にはおそらく要らないハズですが、新規のアカウントの場合には必要になるかと思います。[Public フォルダの用途](https://www.dropbox.com/help/16)の下の方に、

![image](https://qiita-image-store.s3.amazonaws.com/0/592/d1e3713a-84ec-a800-57af-354888201bd3.png)

このような表示があるので、赤線で示したリンクをクリックしてください。Public フォルダーが作成されて、無事に Public フォルダーが使えるようになりました。既に Public フォルダーが有効になっているアカウントで実行すると、「既に有効になっています」だったか、そのような趣旨のメッセージが出てくるだけで、特に害はありませんでした。
情シスの役割について考えてみる


2015/4から2015/9までの半年間、情シスとして働いていました。

もともとその会社には情シス部というのが存在したわけではなく、総務やちょっとわかる人が担当していた状況の中、はじめて情シスができましたという状態。

そのときに、情シスとしては何をやらなきゃいけないのか、ということで、まずはGoogleさんで「情シス」というワードでヒットした記事を読みながら、自分でなるほどと思った点をメモった記録を、今更発掘したので、さらしておくことにしました。

## はじめにやる事

### 社内インフラのヒアリング
- ネットワークはどうなっているの？
	- ベンダーさんにおまかせで、導入している場合が多いです。また、こちらからどのような要件をだせばいいのかをわかっていない場合もあり、ベンダーさんとしても、一般的にだいたいこれくらい？という形で導入している場合があります。そのときに確認しておくこと
		- 割り当てられている社内のIPアドレスの範囲。
			- 実は足りなくなりそうな気配があっても気づかれていません。
		- 野良無線LANがたっていたりしませんか？
		- 障害が発生した場合のエスカレーションフローはある？
			- ある場合は、第一に連絡来る人が誰か、携帯にくるようにしているのかメールにしてあるのかを確認しましょう  

- 社内サーバなど
	- メール・WebサーバのOSが古くないですか？
	- だいたいNTTの古いのを使っているパターンが多いので、乗り換えられるなら、もっと管理画面が充実しているもののほうがいいかもしれません。
	- SSLの更新とか忘れずにやるようになっていますかね、とか。
	- ファイルサーバ、何つかっていますか？NASでもいいですが、セキュリティやバックアップは万全に整っていますか？リカバリ手順とかちゃんと試しておきたいところ・・

### 契約関連の確認

- ライセンスは適正にそろっていますか？
- もう使っていないのに契約だけ継続しているものとかないですかね？

## リスクを経営陣に説明しよう

現状の状態を放置しておくと、何が危険であるかのリスクを経営陣に説明しよう。
まず、現状をヒアリングした状況を、わかりやすくまとめましょう（横文字少なめ）
その上で、現状のリスクとそれがどういう確率で起きそうか、リスクを対処する優先順位と価格を提示してあげましょう。
事業継続できなくなるよ、というリスクを具体的に説明して、それを回避するためのコストを具体的に説明しよう。

## Windows系の技術の知識も必要

開発者だからMacなんですよ・・・と思いつつ、コントロールパネルにたどり着くまでに時間がかかる技術者って、あきらかに怪しい目でみられます。
いや、ちょっと、そっち方面ではないのですよ・・・という思いもありつつ、情シスさんってWindows系の知識がないとだめですね。

- ActiveDirectoryとかセキュリティグループの管理方法
- 古いOSを使っている場合だと何が危険か。セキュリティアップデートされていない状態だとどうなるか。とか現場にわかりやすく説明できるスキルも必要です。

## イントラネットサイトを活用しよう

たぶんGoogleAppsなりOffice360などを導入している会社さんが多いかと思います。
メールで全体周知が多くなってしまいがちですが、有用な情報をイントラネット上にアップしておけば、そこから探してくれるようにいずれはなります。
FAQなど充実させておくのもよいかもしれません。


## 他の企業の実例

### 縁の下から表舞台まで、「情シス」の常識を変える社内起業家の働き方

http://mydeskteam.com/casefile/1304/


* システムの機能が本当にわるいのか、鵜呑みにせずに自分の目で確かめる。
* 関係者が状況を理解し、お互いの目線をそろえるための場を利用すること
	* 毎週定期的に営業系の部長を集めて、業務改善の打ち合わせ
	* テーマ別に業務フローを描いて、役割を整理する
	* もつれた状態を解きほぐし、みんなが納得しやすいプロセスを経ることが大事
	

### パネルディスカッション：クラウド時代の情シスのあり方［前編］。Developers Summit 2014 － Publickey 

http://www.publickey1.jp/blog/14/developers_summit_2014.html


![代替テキスト](http://www.publickey1.jp/blog/14/devs02.jpg)

* 社内の情シスはよりビジネスに近いレイヤにいくかたち
* 半年後、来年に何を作ろうかというユーザー部門とのフリーディスカッションみたいなのをあえて設けて、明日の話とかいまのトラブルの話ではなくて、ちょっと先の話をしましょうと、そこには部門長もちゃんと出てくれと。 
	* 半年後、来年に何を作ろうかというユーザー部門とのフリーディスカッション
	* 明日の話とか今のトラブルの話
	
			
### 攻める情シス 
kintoneの活用で、Excelを撲滅したぜ！というお話
http://www.slideshare.net/kazukimurahama/ss-36920876


## とはいえ

やはり開発をしたいので、情シス担当者としては半年だけでやめました。
でも、課題の多い領域だなとも思ったし、できれば、会社設立当初からそういう担当者をいれておけば、本当に効率のよいIT投資ができると思っています。
なので、スキルの持った人は人件費が高いと思わず、将来にわたって最適なIT投資をしていくためにも、判断ができる人を一人雇っておくのは大事ではないでしょうか。

レンタルCTOならぬ、レンタル情シス担当でもいいかと思いますが。。


ネタとしてはいろいろありました。

トラブルはすべてシステム部門が犯人なのか | あるある日記 | 東洋経済オンライン | 新世代リーダーのためのビジネスサイト http://toyokeizai.net/articles/-/82669
RxSwiftでPromiseのような記述方法

RxSwiftを使って、Promiseみたいに、いくつかの非同期処理を通して、
結果を取得する記述方法を紹介したいと思います。

まず、ストリームに対して、様々な処理を加えた結果を取得したい場合
以下のように書くことが出来ます。

```swift
let number = Variable(1)

number.map
    { number in
        return number + 1
    }
    .map { number in
        return number * 2
    }
    .subscribeNext { number in
        // number = 4
}
```

次に、このmapの中で非同期処理を行いたい場合は、
以下のように、Observableを生成することで実現可能です。

```swift

let number = Variable(1)

number.map
    { number in
        create { (observer: AnyObserver<Int>) in

            非同期処理() {
                observer.onNext(number + 1)
                observer.onCompleted() // 呼ばないとストリームが詰まります
            }                    
            return NopDisposable.instance
        }
    }
    .concat() or .merge() or .switchLatest() // 上記の非同期処理をどのように処理するか決定
    .map { number in
        create { (observer: AnyObserver<Int>) in

            非同期処理() {
                observer.onNext(number + 1)
                observer.onCompleted()  // 呼ばないとストリームが詰まります。
            }                    
            return NopDisposable.instance
        }
    }
    .concat() or .merge() or .switchLatest() // 上記の非同期処理をどのように処理するか決定
    .subscribeNext { number in

            // number == 3
    }
    .addDisposableTo(self.disposeBag)
```

以下の３つのメソッドは`ObservableConvertibleType`で定義されているものです。

```
.concat()
.merge()
.switchLatest()
```

`switchLatest()` は
非同期処理が実行中に次のイベントが来た場合、既存の非同期処理を止めて、あたらしいイベントを元に非同期処理が始まります。
concat,mergeは止まることなくすべての非同期処理を実行しますが、concat,mergeのお互いの違いがわかりませんでした。
errorが発生した時の挙動が異なるようです。

また、これらを挟まずにmapを連結すると、 `Observable<Observable<Int>>` と、Observableがネストされてしまいます。


> [http://muukii.me/2015/11/10/rxswift-promiss/]()
VirtualBoxのVM上のCentOS7.1+Dockerでpipeworkを使って固定IP化してみる

# VirtualBoxのVM上のCentOS7.1+Dockerでpipeworkを使って固定IP化してみる

## 背景

VirtualBoxのVM上のCentOS7.1+Dockerを開発環境のベースにしようと考え中なのですが、IPアドレスをDockerが勝手に割り振ってしまう＋NAPTでポートの設定が面倒、というところからpipeworkで固定IP化して仮想ブリッジ経由でホストからアクセスできるようにしてみたいと思います。こうすることで、VirtualBoxのホストからDockerのコンテナにポートの設定を気にせず直接アクセスできるようになります。

なお、世の中的にはDockerでpipeworkを使うのは非推奨の流れのようですが、2015/11/19時点でお手軽に試せるので使ってみました。

## 参考にした情報

ほとんどこちらの記事を参考にさせていただきました。

- [コンテナに固定IPを割り振って外部からアクセスする](http://qiita.com/Ki4mTaria/items/3425c48e8c6006564cba)

## 前提

- VirtualBoxのVMにCentOS 7.1とDockerをインストール済みとします

## 設定手順

### VirtualBoxのVMの設定変更

仮想ブリッジと関連付けるネットワークアダプターを別途追加します。用途に応じて「ホストオンリーアダプター」か「ブリッジアダプター」を追加します。

また、追加したネットワークアダプターの「プロミスキャスモード」を「すべて許可」に変更します。

### 仮想ブリッジを作成

まずbridge-utilsをインストールします。

```
# yum -y install bridge-utils
```

仮想ブリッジを作成します。

```
# nmcli con add type bridge ifname br0
# nmcli con modify bridge-br0 bridge.stp no
```

次に、追加したネットワークアダプターがブリッジの場合は、以下のようにブリッジするネットワークと同じネットワーク上の仮想ブリッジに割り当てるIPアドレス(x.x.x.x)、ゲートウェイアドレス(y.y.y.y)、DNSサーバアドレス(z.z.z.z)を設定します。

```
# nmcli con modify bridge-br0 ipv4.method manual ipv4.address x.x.x.x/24 ipv4.gateway y.y.y.y ipv4.dns z.z.z.z
```

追加したネットワークアダプターがホストオンリーの場合は、以下のようにブリッジするホストオンリーアダプターのネットワーク上の仮想ブリッジに割り当てるIPアドレス(x.x.x.x)を設定します。

```
# nmcli con modify bridge-br0 ipv4.method manual ipv4.address x.x.x.x/24
```

次に、作成した仮想ブリッジと追加したネットワークアダプターを関連付けます。ここでは「eth2」を関連付けていますが、各自の環境に合わせて調整してください。

```
# nmcli con add type bridge-slave ifname eth2 master bridge-br0
```

### サーバ再起動

いったんサーバ再起動して仮想ブリッジを有効化させます。以下のコマンドで設定内容を確認できます。

```
# brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.080027bc11fa       no              eth2
docker0         8000.0242fd49b7c0       no
```

### pipeworkのインストール

Githubのリポジトリからgit cloneしてきます。

```
# yum -y install git
# cd /usr/local/src
# git clone https://github.com/jpetazzo/pipework.git
# ln -s /usr/local/src/pipework/pipework /usr/local/bin/

```

## 使用方法

起動したコンテナのコンテナIDを取得します。docker psで確認できます。

追加したネットワークアダプターがブリッジの場合は、コンテナに設定したいIPアドレス(a.b.c.d)、ゲートウェイアドレス(y.y.y.y)を使って以下のようにします。

```
# pipework br0 コンテナID a.b.c.d/24@y.y.y.y
```

追加したネットワークアダプターがホストオンリーの場合は、コンテナに設定したいIPアドレス(a.b.c.d)を使って以下のようにします。

```
# pipework br0 コンテナID a.b.c.d/24
```

## 注意点

docker stopするとpipeworkでの設定内容がクリアされるので、再度pipeworkで設定する必要があるようです。