OmniAICreator/Qiita-1.07M huggingface dataset:
セッションに関して


セッション管理とは、Cookie(セッションID)をクライアントユーザとサーバ側で送受信させあうことで交信状態を保持/管理するための仕組み



##セッション/訪問

Webサイトにアクセスして行う一連の行動(まとまった動作の流れ)

例
通信の開始から終了
ログインからログオフ
Webサーバとの接続から情報の要求と応答を経て切断までを一つのセッション単位

##セッションID

アクセス中のユーザの識別や行動の補足(セッション管理)のために付与される固有の識別情報。

ユーザがアクセス/ログインした際に発行され、一定時間アクセスがなかったりログアウトすると破棄される。

HTTPではセッション管理の仕組みが用意されていないため(注1)、ユーザを識別する手法として最初にサーバがセッションIDを発行し、通信の際にはユーザ-とサーバ-が必ずセッションIDを送受信することにより、ユーザ-ごとに適した情報を提供する制御が可能となる。

注1
HTTPリクエストは基本はステートレスな為、セッションIDが保持されない。そのためセッションという機能を用いてステートレスな通信規約をステートフルな状態へと変化させる。

##Cookie

「セッションIDやセッション名」を送受信するため使われる機能がCookieであり、ブラウザに保存される小さなテキストデータファイルである。
Webサーバーで発行されたセッションIDをクライアントユーザーのブラウザのCookieにもたせることで、クライアントがサーバにアクセスしたたびに、テキストデータファイル内の情報をサーバ側に送信し、クライアントとサーバの交信状態を保持させ、特定のユーザーであることをサーバに識別させる。。

##セッション管理

WWWサービスで使用されるHTTPプロトコルはクライアントからWebサーバーへのリクエストがあるたびに、「クライアントとサーバー間でコネクションが成立し、リクエストに対す応答が行われ、コネクションが切断される。

そのため、Webサーバーに対する複数リクエストが同一のクライアントから送信されたものであるかどうかは判断不可能。

例えば電子商取引サイトのようにWebサーバにユーザーがログインしてからログアウトするまで、ログイン情報を保持したままページの移動をするにはこのままでは問題がある。

そこで「クライアントとサーバー間でその情報を保持し、アクセス制御を一つの集合体として管理する仕組み」それがセッション管理となる。
six apart さんからの挑戦状 #yapcasia 


無限コーヒーのカップに書いてあるコードを転記してみた。

# vim カップ

```perl
#!/usr/bin/env perl
$_ = 'Drink coffee! Supported by Six Apart';
tr/a-z/Blogging after this event!/;
tr/N-ZA-z/A-za-m/;

@m = split //, $_;
$j = sub { join(chr(0), @_) };
$_ = chr(104) . $j->(@m[10, 11]) . pack("H*", join('', qw/70 3a 2f 2f/));
$_ .= $m[4] . chr(46) . $m[4] . '<3';
$_ .= 'x' . $m[29] . chr(112) . $j->(@m[29, 15, 10]) . chr(46) . 'Asia/Tokyo';
$_ .= chr(47) . $j->(@m[24, 29]) . chr(112);

s!/Asia/Tokyo!jp!;
reverse; tr.ap.a xis.;
$anniversary = 10;
y.apc.asia.;
$_ .= chr('10th' * $anniversary - 1);
$_ .= '2015';
y. ET ANOTHER .pERL HACKER.;
s/<3/i/g;
print;
```
Simple Skyで素敵な空 一枚のテクスチャで一日の空の演出

##Simple Sky
こちらの無料のアセットが空の演出に使いやすかったので・・・。 
<a href="https://www.assetstore.unity3d.com/jp/#!/content/42373" target="_blank">![131.png](https://qiita-image-store.s3.amazonaws.com/0/46444/98c90c41-1f9b-afca-935d-74d91bffce82.png)</a>

##パッケージをインポートしたところ
![スクリーンショット 2015-08-22 13.16.58.png](https://qiita-image-store.s3.amazonaws.com/0/46444/dbaff61c-2ef0-7581-1005-8f6061da5400.png)

モデルが複数ありますがテクスチャは１枚でこれをUVでスクロールさせることで一枚の画像で昼も夜も表現可能です。
シーンを見るとSkyDomeが空のprefabでその下に月や星、太陽があり、雲はCloudsの下にあるので
Activeを切り替えるだけでOK
![スクリーンショット 2015-08-22 13.20.54.png](https://qiita-image-store.s3.amazonaws.com/0/46444/4e92174f-3811-e5c8-b3c2-4a02248e205c.png)

##手動で動かしてみたところ
![sky.gif](https://qiita-image-store.s3.amazonaws.com/0/46444/9fd165c3-9a41-9ed0-de2e-1d34e39e86f5.gif)

##ソースをちょろっと書いてScriptで動くように
```csharp
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class SkyManager : MonoBehaviour {

	public Transform skyTran;
	public Transform croudParentTran;
	public GameObject star;
	public GameObject sun;
	public GameObject moon;
	public Material skyMaterial;

	private List<Transform> croudList;
	private float timeSpeed = 5f;   // 5秒で一周するように
	private float skyRotateSpeed = 0;  
	private float cloudMoveSpeed = 1f;
	private float nowTime = 0;
	

	void Awake()
	{
        skyRotateSpeed = 360f/timeSpeed;
		croudList = new List<Transform>();
		foreach(Transform tran in croudParentTran)
		{
			croudList.Add (tran);
		}
	}

	void Update () {
		nowTime += Time.deltaTime;
		float nowValue = Mathf.Clamp(nowTime / timeSpeed, 0f, 1f);
		if(nowTime > timeSpeed) nowTime = 0;
		skyMaterial.SetTextureOffset("_MainTex", new Vector2( nowValue, 0 ));
		skyTran.Rotate (new Vector3(0, skyRotateSpeed * Time.deltaTime, 0));
		foreach(Transform tran in croudList)
		{
			tran.transform.position += new Vector3(cloudMoveSpeed * Time.deltaTime, 0, 0);
		}

		if(0.2 < nowValue && nowValue < 0.6f)
		{
			star.SetActive(true);
			moon.SetActive(true);
			sun.SetActive(false);
		}
		else
		{
			star.SetActive(false);
			moon.SetActive(false);
			sun.SetActive(true);
		}
	}
}
```
![sky2.gif](https://qiita-image-store.s3.amazonaws.com/0/46444/df4913ef-eb02-956a-d5b4-d330f279abe1.gif)

うんいい感じ

###画像一枚で昼よるってどんな感じのテクスチャ展開なんだろう・・・。
と思ったのでみてみました。

空
![スクリーンショット 2015-08-22 13.49.48.png](https://qiita-image-store.s3.amazonaws.com/0/46444/b2e5efd5-eb10-3cc9-f7f4-92441a28a0ba.png)
全て真ん中によってる。なるほど。  

こちら雲
雲は下の方に一直線
![スクリーンショット 2015-08-22 13.53.49.png](https://qiita-image-store.s3.amazonaws.com/0/46444/f46c8ab0-b238-87a1-fc50-8219e1b4dd3f.png)

太陽と月は上の方に
![スクリーンショット 2015-08-22 13.53.13.png](https://qiita-image-store.s3.amazonaws.com/0/46444/4a2d7d09-7800-f57d-f536-cb0d0c6a8f89.png)

こう作るのかと関心してしまった。覚えておこう。
mysqlが起動できない場合: No directory, logging in with HOME=/

## 参考

* [MySQLを起動すると「No directory, logging in with HOME=/」と表示される - 日常メモ](http://d.hatena.ne.jp/graySpace/20140915/1410741641)

## 原因

```bash:
$ grep mysql /etc/passwd
mysql:x:106:111:MySQL Server,,,:/nonexistent:/bin/false
```

HOMEが /nonexistent になっている。

## 修正

```bash:
usermod -d /var/lib/mysql mysql
mysql_install_db
```

これで起動できるようになる。
（なお /nonexistent を作ってmysql権限にしても起動できなかった。）
ファンタジー生産管理システムの開発2.5

[ファンタジー生産管理システムの開発2](http://qiita.com/moto_pipedo/items/90379e1bdd6721967561)の続きです。
WindowsマシンにPostgreSQL 9.4.4をインストールしてみました。
※もともと9.3をインストールしてあったので、各種アンインストール後、postgresユーザーを削除してから実施しました。

## TL;DR
PostgreSQL使いやすい！

+ PostgreSQL＝BSDライセンスで公開されているRDBMS
+ pgAdmin IIIというGUIツールが付属
    + SQLに詳しくない人でも直感で環境構築＆テーブル作成ができる
+ フリーソフトのA5:SQL Mk-2からもDBに接続可能
    + SQLによるデータ操作やテーブル定義書作成などの恩恵あり
+ オープンソースのライブラリNpgsqlを使えばC#からPostgreSQLに接続できる

## 女騎士さんは「SQL初心者」のスキルを手に入れました

### PostgreSQLまわりについてメモ
+ PostgreSQL＝BSDライセンスで公開されているRDBMS
+ Oracle、MySQLとよく比較される
+ PostgreSQLはテーブルパーティショニング機能を標準機能として使える
    + 巨大なテーブルに対して設定することはあるかも
    + 古いデータの退避・インデックス作成以外にもパフォーマンスをチューニングする手段があるということ
+ ライブラリNpgsqlについて
    + C#からPostgreSQLのデータを操作するライブラリ
    + [http://www.npgsql.org/about.html](http://www.npgsql.org/about.html)のLicenceおよびNuGetのライセンスを読む限り、BSDライセンス

### インストール＆環境構築
+ Windowsへのインストールは基本デフォルトのままでNext連打
+ postgresユーザーのパスワードは忘れないようにメモする
    + インストール後、DB作成などはこのpostgresユーザー（スーパーユーザー）で作業する
+ **WindowsOSアカウントにもpostgresユーザーを作成する**必要がある
+ インストール直後、postgresというDBがあるが、ここにはテーブルを作らずに作業用に別DBを作る
+ pgAdmin IIIで環境構築できる（SQL書かなくても）
    + なぜ象なんだ。かわいいけど
+ 作業用ユーザー作成→作業用DB作成の順で良いはず（いずれもpostgresユーザーで作業。ユーザー＝ログインロール）
+ 作業用DBのオーナーは作業用ユーザーにしておく
    + もし、DBの権限とか分からなかったらとりあえず作業用ユーザーに全て与えておく
        + テーブルとか作りたいので
+ 作業用DBを作業用ユーザーで操作する
    + [A5:SQL Mk-2](http://www.wind.sannet.ne.jp/m_matsu/developer/a5m2/)からもDBに接続可能
        + SQLによるデータ操作やテーブル定義書作成などの恩恵あり
+ DBの中にはスキーマがある
    + デフォルトでpublicスキーマ
    + 複数のスキーマを持たせることも可能で、テストとかに便利かも
+ 作業用DBにテーブルなどのオブジェクトを作る
    + スキーマを指定はとりあえず意識しなくて良い
    + スキーマ指定しなれけば自動的にpublicスキーマに作られる
+ テーブルなどのオブジェクト作成時の名称は**小文字**が便利
    + 小文字で作成した場合（test_tableを作成）
        + select * from test_table; → OK
        + select * from TEST_TABLE; → OK
    + 大文字で作成した場合（TEST_TABLEを作成）
        + select * from test_table; → NG
        + select * from TEST_TABLE; → NG
            + 「リレーション"test_table" が存在しません」のようなエラーになる
            + 大文字で作成したテーブルも""で囲めば一応selectできる
+ オートシーケンス付きのテーブルも作れる
    + シーケンスを作成
    + テーブルを作成
    + テーブルのオートシーケンスしたい列の初期値に`nextval('シーケンス名'::regclass)`を設定する
+ 文字列データは文字列長を指定しないで一律text型でも可
    + 使う文字数があらかじめ分かっているときはcharacter varying型にすると良い
        + DBサイズ見積りの目安になることがある
    + character型を使うメリットはあまりないらしい
        + 使うとしたら'Y'/'N'フラグのときぐらいか
            + そんなときはboolean型使えよ、だと……（くっ、殺せ）

## 前回のソースを直してみた
[ファンタジー生産管理システムの開発2](http://qiita.com/moto_pipedo/items/90379e1bdd6721967561)のデータまわりをPostgreSQLに担当してもらった。

GitHub始めました。[→こちら](https://github.com/motopipedo/FantasyProductionManagementSystem)
GitやGitHubの作法が合ってるか分からない……。

## 今後の方針メモ
**テーブル名の仮ルール**

+ 一時的な表はa始まり（例：一時表atmp）
+ マスタテーブルはm始まり（例：取引マスタmtrd）
+ トランザクションテーブルはt始まり（例：受払履歴treciss）

### オークさんと一緒に作る予定
+ 実地棚卸
    + 理論在庫と実在庫の差分が発生する
+ 受払の記録を強化する
    + 工程・製造品と紐付ける
    + 理論値で受払する
+ BOM
    + 理論値で計算するための根拠となる
+ 品目マスタ
    + リードタイム
+ 簡易的なMRP
    + 有効在庫とリードタイムから所要量を計算する
    + 指図を作る
OSX Yosemiteでmakeコマンド等で使うnprocを実現したい

# 概要
Linuxではnprocコマンドを利用すると、利用出来るCPUの数を表示出来るので

```
make -j $(nproc) ...
```

的なコマンドが利用出来るのですが、先ほど試した所OSXには標準でついていないコマンドのようでした。

代替コマンドも無かったので、OSXで使えるnproc代替コマンドをbashとgolangで作ってみました。

## 新Bashスクリプト 2015-8-22 16:00追記

下の旧Bashスクリプトよりも速いのでこちらを推奨。
動かない場合は下のを使ってみてください。

```nproc.sh
#!/bin/bash
getconf _NPROCESSORS_ONLN
```

## 旧Bashスクリプト
```nproc.sh
#!/bin/bash
system_profiler SPHardwareDataType | grep "Total Number of Cores" | awk '{print substr($5, 1)}'
```

system_profilerはそのまま実行すると、出力が多すぎて糞重いのですが引数にプロファイルのタイプを指定すると、割と軽快に動作してくれます。
プロファイルタイプのリストは
```system_profiler -listDataTypes```で一覧が取得出来ます。

ファンクション化して読み込むなり、PATHの通ったディレクトリに放り込んでください。

## Golangスクリプト
```nproc.go
package main

import (
    "runtime"
)

func main() {
    println(runtime.NumCPU())
}
```
Go言語は本当にシンプルですね。
ビルドしてPATHの通ったディレクトリに突っ込むと幸せになれるかもしれません。

あまり使う機会は無いかもしれませんが、Linuxと同じように使いたい場合や共用スクリプトに利用したい場合活用下さい。
c > readUInt32()の間違い


以下の実装には間違いがあります。どこでしょう？

```c
uint32_t readUInt32()
{
	char buf[10] = {0};
	int size = sizeof(uint32_t);
	m_fileStream->Read(buf, size);

	uint32_t res = 0;
	for(int idx=(size-1); idx>0; idx--) {
		res = res + buf[idx];
		res = res << 8;
	}
	res = res + buf[0];

	return res;
}
```

正解のコードはこちら

```c
uint32_t TELFReader::readUInt32()
{
//	char buf[10] = {0};
	unsigned char buf[10] = {0};
	int size = sizeof(uint32_t);
	m_fileStream->Read(buf, size);

	uint32_t res = 0;
	for(int idx=(size-1); idx>0; idx--) {
		res = res + buf[idx];
		res = res << 8;
	}
	res = res + buf[0];

	return res;
}
```

char型で宣言した場合、コンパイル環境によってはsigned charになり、buf[.]の値がマイナスとなる時があり、読み取りに失敗する。
[LittleBits] 昇圧型５Ｖ電源を自作してみた


LittleBits は面白いですね。インタフェースの簡素化はソフト屋にとっては魅力です。でも、いかんせん高い。
そもそも、作って、分解して違うのを作って、ていうループは、なにも残らなくて辛いのです。
学研の電子ブロックもそうですけど、この LittleBits の問題はそこにある。と思うんですよ。とにかく一発勝負すぎる。

だいたい工作って言ったら、作ったものを並べて、放置して、あとで

**「ああ、俺はこんなにゴミを作っちまったのか・・」**

という罪悪感が醍醐味なわけじゃないですか。部品が安くないと、これができない。

とりあえず LittleBits の開発キットを入手したのですが、これも高い。高いよ！
これじゃゴミを作りっぱなしにできない。
というわけで、せめて LittleBits のコネクタだけでどれだけ頑張れるか、という戦いが始まるわけです。
ゴミを作る戦いです。

#とりあえず電源から
もちろん電源は LittleBits に付属しているんですが(9V電池)、無くなると廃棄するしかない電池ってあまり使いたくないんですよね。
環境がどうとかそういうことでもなくて、正しく捨てるのが面倒といいますか、アマゾンで電池をクリックするのが億劫といいますか。
使いまわせるものは使いまわしたいのです。
なので充電池を使うんですが、５Ｖ出力するために６本とか８本とか並べたくありません。
どうせたいした電流はいらないんだから（必要になったらまた考える）、単四充電池２本を昇圧して５Ｖ出します。

#モデリングします
モデリングの前に LittleBits のコネクタの形状を計測する必要がありますが。そこはノギスでがんばります。

![スクリーンショット 2015-08-22 11.02.59.png](https://qiita-image-store.s3.amazonaws.com/0/90046/c5adab6a-324e-a3ae-5404-f3089872436b.png "スクリーンショット 2015-08-22 11.02.59.png")

下の溝にコネクタがはまります。上の溝には基盤が差し込まれます。
３Ｄプリンタを入手してから、徐々にモデリングも板についてまいりました。テクスチャ貼る技とかは一切身につきませんけど。

#プリントアウトします
サポート材を指定します。どの向きで印刷するかは経験と勘で。
![スクリーンショット 2015-08-22 11.05.58.png](https://qiita-image-store.s3.amazonaws.com/0/90046/1cdd6719-546e-e221-92c0-d5389dc49501.png "スクリーンショット 2015-08-22 11.05.58.png")

#昇圧回路を作ります
こちらのページを参考にしています。
http://blog.goo.ne.jp/jsbach2005/e/1f134b1cdc9b5b47ed1a8631b2e83ccd
当該ページは2008年09月05日ですが、現在でも有効であることをここに記しておきたいと思います。
最低限の情報として回路図も書きましたが、詳細は元ページを参照ください。
実は同等の昇圧回路がが秋月とかで５００円で売ってますけど、ゴミを作るのに５００円はちょっと高いのです。

![5Vcircuit.png](https://qiita-image-store.s3.amazonaws.com/0/90046/815ba403-9e9f-37f8-e133-1395766fc6a4.png "5Vcircuit.png")

#完成
こうなりました。充電電池２本（2.5V程度）でもちゃんと 5V でてます。LittleBits のパーツとも接続できてます。
せまいところにがんばって並べました。
![IMG_1374.jpg](https://qiita-image-store.s3.amazonaws.com/0/90046/80ad00fc-68e9-4e8a-8094-afd480b82c20.jpeg "IMG_1374.jpg")

コネクタ部。３Ｄプリンタでギリギリのサイズに作ると、パシっとはめるだけで固定できます。
![IMG_1376.jpg](https://qiita-image-store.s3.amazonaws.com/0/90046/41be9045-5029-99ab-e75e-d154c7395d29.jpeg "IMG_1376.jpg")


肝心のコネクタと結線するのが苦しいんですよね・・
![IMG_1375.jpg](https://qiita-image-store.s3.amazonaws.com/0/90046/49a5ea07-9f2e-f98e-d309-d0b3e36fbf2c.jpeg "IMG_1375.jpg")


#次がんばる
やっぱコネクタとの結線が課題。線を伸ばすんじゃなくて、ユニバーサル基盤を加工するのがよさそうだなあ。
こうしてゴミが増えていくわけです（主目的）。
elfsharp > ReadUInt32()の構造

unsigned int32を読み込む処理 ReadUInt32() の追跡

```csharp
public uint ReadUInt32()
{
  ReadInternal(buffer, 4);
  return bitConverter.ToUInt32(buffer, 0);
}
```

```csharp
public uint ToUInt32 (byte[] value, int startIndex)
{
  return unchecked((uint) (CheckedFromBytes(value, startIndex, 4)));
}
```

```csharp
long CheckedFromBytes(byte[] value, int startIndex, int bytesToConvert)
{
  CheckByteArgument(value, startIndex, bytesToConvert);
  return FromBytes(value, startIndex, bytesToConvert);
}
```

CheckByteArgument()は例外処理。

```csharp
/// <summary>
/// Convert the given number of bytes from the given array, from the given start
/// position, into a long, using the bytes as the least significant part of the long.
/// By the time this is called, the arguments have been checked for validity.
/// </summary>
/// <param name="value">The bytes to convert</param>
/// <param name="startIndex">The index of the first byte to convert</param>
/// <param name="bytesToConvert">The number of bytes to use in the conversion</param>
/// <returns>The converted number</returns>
protected abstract long FromBytes(byte[] value, int startIndex, int bytesToConvert);
#endregion
```

```csharp
protected override long FromBytes(byte[] buffer, int startIndex, int bytesToConvert)
{
  long ret = 0;
  for (int i=0; i < bytesToConvert; i++)
  {
    ret = unchecked((ret << 8) | buffer[startIndex+bytesToConvert-1-i]);
  }
  return ret;
}
```
elfsharp > ToUInt32()

unsigned int32を読み込む時に使われる ToUInt32()

[elfsharp/ELFSharp/MiscUtil/EndianBitConverter.cs](https://github.com/konrad-kruczynski/elfsharp/blob/0a361d9feaa4b4282c929a3de060198e1385d571/ELFSharp/MiscUtil/EndianBitConverter.cs)

```csharp
/// <summary>
		/// Returns a 32-bit unsigned integer converted from four bytes at a specified position in a byte array.
		/// </summary>
		/// <param name="value">An array of bytes.</param>
		/// <param name="startIndex">The starting position within value.</param>
		/// <returns>A 32-bit unsigned integer formed by four bytes beginning at startIndex.</returns>
		public uint ToUInt32 (byte[] value, int startIndex)
		{
			return unchecked((uint) (CheckedFromBytes(value, startIndex, 4)));
		}
```

~~単純なUInt32型読込みではないようだ。~~

やっていることはUInt32の読み取りに例外処理などしているものだった。
Doctrine2で管理されているエンティティを列挙する

コントローラーで取得する場合は

```php
$manager = $this->get('doctrine')->getManager();
foreach ($manager->getMetadataFactory()->getAllMetadata() as $meta) {
    var_dump(
        $meta->getName(),
        $meta->getReflectionClass()
    );
}
```

このような感じ。（実際にコントローラーで取る機会はないと思うけど）

ここで取れる `$meta` については 
See: https://github.com/doctrine/common/blob/master/lib/Doctrine/Common/Persistence/Mapping/ClassMetadata.php
See: https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
などを参照
elfsharp/csharp > unchecked((SectionFlags)RawFlags);


[elfshap](https://github.com/konrad-kruczynski/elfsharp/blob/0a361d9feaa4b4282c929a3de060198e1385d571/ELFSharp/MiscUtil/EndianBinaryReader.cs)

上記で使われている unchecked()という関数はgithubレポジトリで検索しても出てこなかった。

```
Flags = unchecked((SectionFlags)RawFlags);
```

https://msdn.microsoft.com/ja-jp/library/a569z7k8.aspx
によるとC#の関数のようだった。

> 整数型の算術演算および変換に対してオーバーフロー チェックを抑制するのに使用します。
...
> たとえば、次の例では unchecked ブロックまたは式で計算が実行されるため、結果が整数に対して大きすぎることは無視され、int1 に値 -2,147,483,639 が代入されます。

```csharp
int1 = unchecked(ConstantMax + 10);
```
snippet: Dockerfile

## 自分用

```bash:自分用コンテナ
docker run -it -d --name dev -h dev.local tukiyo3/ubuntu-dev
```

```bash:秘密鍵を取得
wget -o ~/.ssh/id_rsa.vagrant \
 https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant
```

```text:~/.ssh/config
Host dev 
    User vagrant
    HostName dev.local
    IdentityFile ~/.ssh/id_rsa.vagrant
```

* http://dev.local
* `ssh vagrant@dev.local`
* `ssh dev -X`

で接続ができる。


## WARNING: Failed to contact D-Bus daemon.

* コンテナ内でdbusサービスが起動していないとこのエラーが出る。

```bash:Dockerfile
CMD service ssh start &&\
    service dbus start &&\
    service avahi-daemon start &&\
    ip a | grep "inet " &&\
    tail -f -n0 /var/log/dmesg
```

## apt-get install時の入力待ちを無効にする

* [ubuntu - How do I ask apt-get to skip any interactive post-install configuration steps? - Server Fault](http://serverfault.com/questions/227190/how-do-i-ask-apt-get-to-skip-any-interactive-post-install-configuration-steps)

```bash:
DEBIAN_FRONTEND=noninteractive \
 apt-get install -y [packagename]
```

## コンテナで/etc/rc2.d/S〜を実行させる

* ubuntu 14.04で確認。

```bash:Dockerfile
CMD /etc/init.d/rc 2 && tail -f /var/log/dmesg
```

## Dockerfile内で ` > `を使う方法

```bash:Dockerfile
RUN (echo /etc/init.d/ssh start > /.bashrc)
```

## CMD でipアドレスを表示

* `ip a s | grep "inet "`

```bash:Dockerfile
FROM tukiyo3/ubuntu-debootstrap-ja:14.10

EXPOSE 22 80 443 8000 8080 3389 5901 5902
WORKDIR /workspace
VOLUME ["/workspace"]

CMD /etc/init.d/rc 2 && ip a s | grep "inet " && tail -f -n0 /var/log/dmesg
```

## kitematicでEXECする時用にSHELL変数指定しておくと便利

```bash:Dockerfile
ENV SHELL /bin/bash
```

指定しておかないと /bin/sh が実行される様子


## kitematic用にVOLUME指定しておくとmountできるので便利

```bash:Dockerfile
WORKDIR /workspace
VOLUME ["/workspace"]
```

![スクリーンショット 2015-08-22 10.19.41.png](https://qiita-image-store.s3.amazonaws.com/0/25728/e3e8fcaa-bd2a-475b-71e3-70da8b443a17.png)

## sshしたい

```bash:Githubから公開鍵を取得
RUN mkdir /root/.ssh && \
    (curl https://github.com/tukiyo.keys > /root/.ssh/authorized_keys) &&\
    chmod 600 /root/.ssh/authorized_keys
```

```bash:Vagrantの公開鍵を取得したい場合
(curl -q https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub > /root/.ssh/authorized_keys)
```

```bash:sshのポートを変更
RUN sed -i.org -e 's/Port 22/Port 10022/' /etc/ssh/sshd_config
```

```bash:--net&nbsp;host
docker run -it --net host イメージ
```

```bash:boot2dockerのipで接続ができる
ssh root@192.168.99.100 -p 10022
```


## 不要になったimageをまとめて削除

* 2週間以上過ぎたnoneなimageを削除する

```bash:clean_none_images.sh
for i in $(docker images | awk /weeks/'{print $3}')
do
  docker rmi $i
done
```

```bash:cronに以下追加
10 10 * * 1 $HOME/cron/clean_none_images.sh
```

## 不要になったimageをまとめて削除2

```bash:docker-cleanup.sh
docker rm `docker ps -a | grep Exit | awk '{print $1}'`
docker rmi `docker images | grep none | awk '{print $3}'`
```

## docker save/load

* [公式document](https://docs.docker.com/engine/reference/commandline/save/#extended-description)
イメージを保存/復元する場合に使用。
* export/import というものもあるが、こちらはレイヤー階層を無視するので注意。

```
docker save sample-image > sample-image.tar
docker load < sample-image.tar
```
Mavericksで2015-004をインストールしたらSSL証明書がおかしくなる件の別解


[Mavericksで2015-004をインストールしたらSSL証明書がおかしくなる件](http://qiita.com/konyavic/items/78f2e0155ad077fe2d0d)と同様の症状で困っていた
App Storeにも接続できず、なんとかUPDATEする方法がないかと思いしらべたところコマンドラインでMac OS XをUPDATEする方法があった

rootシェルになる

```bash
$ sudo -s
```

アップデートの確認

```bash
# softwareupdate --list
```

アップデート内容の例

```bash
Software Update Tool
Copyright 2002-2012 Apple Inc.

Finding available software
Software Update found the following new or updated software:
   * RemoteDesktopClient-3.8.3.1
	Remote Desktop クライアントアップデート (3.8.3.1), 7103K [recommended]
   * Mac EFI Security Update 2015-001-1.0
	Mac EFI セキュリティアップデート 2015-001 (1.0), 102537K [recommended] [restart]
   * Safari7.1.8Mavericks-7.1.8
	Safari (7.1.8), 59703K [recommended]
   * SecUpd2015-006Mavericks-1.0
	セキュリティアップデート 2015-006 (1.0), 250883K [recommended] [restart]
   * iTunesX-12.2.2
	iTunes (12.2.2), 221488K [recommended]
```

アップデート

```bash
# softwareupdate --install 'SecUpd2015-006Mavericks-1.0'
```

アップデートの実行結果

```bash
Software Update Tool
Copyright 2002-2012 Apple Inc.

Finding available software

Downloaded セキュリティアップデート 2015-006
Installing セキュリティアップデート 2015-006
Done with セキュリティアップデート 2015-006
Done.

You have installed one or more updates that requires that you restart your
computer.  Please restart immediately.
```

これで再起動したらApp Storeなども表示できるようになった

## 参考文献
* [コマンドラインを使ってソフトウェアアップデートをリモートインストールする方法](https://support.apple.com/ja-jp/HT200113)
* [Mavericksで2015-004をインストールしたらSSL証明書がおかしくなる件](http://qiita.com/konyavic/items/78f2e0155ad077fe2d0d)
windows7の休止モードを止める


調べたら書いてあるんだけども一応メモしとく。


休止状態を無効にするには、以下の手順を実行します。
[スタート] ボタンをクリックし、[検索の開始] ボックスに「cmd」と入力します。
検索結果の一覧で、[cmd] を右クリックし、[管理者として実行] をクリックします。
ユーザー アカウント制御からメッセージが表示される場合は、[続行] をクリックします。
コマンド プロンプトで、「powercfg.exe /hibernate off」と入力します。
「exit」と入力し、Enter キーを押して、コマンド プロンプト ウィンドウを閉じます。
休止状態を有効にするには、以下の手順を実行します。
[スタート] ボタンをクリックし、[検索の開始] ボックスに「cmd」と入力します。
検索結果の一覧で、[cmd] を右クリックし、[管理者として実行] をクリックします。
ユーザー アカウント制御からメッセージが表示される場合は、[続行] をクリックします。
コマンド プロンプトで、「powercfg.exe /hibernate on」と入力し、Enter キーを押します。
「exit」と入力し、Enter キーを押して、コマンド プロンプト ウィンドウを閉じます。
https://support.microsoft.com/ja-jp/kb/920730
Pythonでその日の任意の時間のdatetimeインスタンスを取得する

#前提

事前にdatetimeをimportしておきます。

```py
from datetime import datetime
```


#その日の0時0分0秒のdatetimeインスタンス

replaceを使って無理やりその日の0時0分0秒にします。

```py
datetime.now().replace(hour=0,minute=0,second=0,microsecond=0)
```

##実行結果

```py
>>> datetime.now().replace(hour=0,minute=0,second=0,microsecond=0)
datetime.datetime(2015, 8, 22, 0, 0)
```

#応用

##タイムゾーンを考える
pytzを利用してタイムゾーンに対応してみます

```py
>>> import pytz
>>> tz = pytz.timezone('Asia/Tokyo')
>>> datetime.now(tz).replace(hour=0,minute=0,second=0,microsecond=0)
datetime.datetime(2015, 8, 22, 0, 0, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)
```



##その年の元日の0時0分0秒のdatetimeインスタンス

上記に加えて1月1日であればよいので以下の通り。

```py
>>> import pytz
>>> tz = pytz.timezone('Asia/Tokyo')
>>> datetime.now(tz).replace(month=1,day=1,hour=0,minute=0,second=0,microsecond=0)
datetime.datetime(2015, 1, 1, 0, 0, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)
```
Failed to mount folders in Linux guest.

## 対象環境 (Environment)
[ubuntu/precise64](https://vagrantcloud.com/ubuntu/boxes/precise64)

```
$uname -r
3.13.0-62-generic
```

## エラーメッセージ (Error Message)
```
$vagrant up
...
Failed to mount folders in Linux guest. This is usually because
the "vboxsf" file system is not available. Please verify that
the guest additions are properly installed in the guest and
can work properly. The command attempted was:

mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3` vagrant /vagrant
mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant` vagrant /vagrant

The error output from the last command was:

stdin: is not a tty
/sbin/mount.vboxsf: mounting failed with the error: No such device
```

## 解決方法 (Solution)
```
$vagrant plugin install vagrant-vbguest
```
「golang 1.5 の internal パッケージの使い方。」を試してみた

# はじめに

mattnさんのブログ記事「[golang 1.5 の internal パッケージの使い方。](http://mattn.kaoriya.net/software/lang/go/20150820102400.htm)」を試してみました。

# ディレクトリー構成

```
$GOPATH/src/github.com/
|
+--mattn/go15internal/
|  +--bar/bar.go
|  +--foo/foo.go
|  +--internal/hello/hello.go
|
+--qt-luigi/go15internal_func/
|  +--func.go
|
+--qt-luigi/go15internal_main/
   +--main.go
```

"`qt-luigi/go15internal_*/`"はローカルで作成したものでGitHubには存在しませんm(__)m

# ソースコード

```go:func.go
package go15internal_func

import (
        "github.com/mattn/go15internal/internal/hello"
)

func Hello() {
        hello.Hello("gopher")
}
```

```go:main.go

package main

import (
        "github.com/mattn/go15internal/internal/hello"
)

func main() {
        hello.Hello("gopher")
}
```

# goツール実行

## go15internal_func/ 配下

```
$ go run func.go 
go run: cannot run non-main package
```
```
$ go build func.go 
$ ls
func.go
```
```
$ go build
package github.com/qt-luigi/go15internal_func
	imports github.com/mattn/go15internal/internal/hello: use of internal package not allowed
```

## go15internal_main/ 配下

```
$ go run main.go 
Hello gopher
```
```
$ go build main.go 
$ ls
main    main.go
$ ./main
Hello gopher
```
```
$ go build
package github.com/qt-luigi/go15internal_main
	imports github.com/mattn/go15internal/internal/hello: use of internal package not allowed
```

# おわりに

internalパッケージの呼び出しでエラーを出してくれるのは"`go build (ファイル指定なし)`"の場合です。私はファイルを指定する手癖があるのでハマりました。q@w@p
T *a[n] はなぜポインタ配列なのか 

>添字演算子`[]`は、参照演算子`*` より優先順位が高い。
>したがって、`T *a[n]`は「T型ポインタを要素とする配列`a`」と読むのが正しい。

最初、これが納得いかなかった。`[n]`は最初に`a`と結合するということは、つまり`T *(a[n])`ということであるから、`a`は「`n`個の要素を持つ配列」というカタマリのオブジェクトを参照するポインタ型となる、ではないのか。これって逆なんじゃないの？、と。

そこで僕は、こんなアナロジーを考えた。

>ウンコ味のカレー。
>カレー味のウンコ。

ウンコとカレーの見た目が似ていると言っても、落ち着いて考えると、「ウンコ味のカレー」は、結局カレーである。「カレー味のウンコ」は、結局ウンコである。「どちらか選べと言われたら、俺はカレー味のウンコを食う」という人は、味がカレーだろうが「ウンコを食べる」のである。再考をお勧めしたい。言い換えると、こうなる。

>ウンコ味のカレーA。　…　Aはカレー（ウンコ味）。
>カレー味のウンコB。　…　Bはウンコ（カレー味）。

味はどうあれ、変数Aが最初に結合するのはカレーであり、変数Bが最初に結合するのはウンコである。この「結局、カレーなのか？ウンコなのか？」という観点を与えてくれるのが、C言語の**型分類**という概念である。

>　型は, その**型分類**(type category)によって特徴付ける。型分類とは, (この節の派生型の解釈の中で規定したように) 派生型を表現する際に最外側に示す型, 又は型が派生型を含まない場合, その型自身のいずれかとする。
>
>*（『プログラム言語C JIS X 3010-1993』「6.1.2.5 型」より引用）*

「型分類とは、派生型を表現する際に最外側に示す型」という定義に注目したい。変数と直接に結合する型が、その変数の型分類（最外側の型）であると考えると、`T *A[n]`において、変数`A`の型分類は配列型（その要素型は「T型ポインタ」型）である。`T (*B)[n]`において、変数`B`の型分類はポインタ型（被参照型は「T型を要素型とする配列」型）である。

変数名と演算子の結合関係をカッコで明示すると

```c:subscript_operator.c
    int *(A[n]);
    int (*B)[n];
```

`(A[n])`は配列型としか読みようが無いし、`(*B)`もポインタ型としか読みようがない。同様に、配列型配列でも

```c:subscript_operator.c
    int A[m][n];
```

添字演算子の結合規則は「左から右」である。上記のコード例における変数Aの型分類は「`m`個の要素を持つ配列」型であり、その要素型は「`int`型`n`個の配列」型である[^1]。これを逆にして「`m`個の要素を持つ配列を要素とする`n`個の配列」と読むのは誤りである。「りんごが5個入った袋が3袋あります」という文章を「`5*3`」ではなく「`3*5`」と立式する、と考えれば分かりやすいかもしれない。

『ポインタ完全制覇 』（前橋和弥著・技術評論社）では、英語の語順で解釈してみることを提案されていたけど、「型分類（最外側の型）は何か？」という観点から考えてみても、最初に結論を述べ、詳細情報を後に付随するという英語の語順が作用しているのは大きいと思う。

[^1]: ちなみに、配列型配列とは「`T`型配列`A`」の`T`がたまたま配列型だった、というだけのことである。よく言われる「Cに多次元配列は存在しない」とは、このことを指す。
開けるけどフィルタをかけると落ちる Excel ファイルをどうにかフィルタリングする PowerShell コマンド


昨日、「PowerShell知っててよかった」と思えたので Qiita に残す。[^1]
[^1]: 会社に PowerShell をわかる人がいないので Qiita に書く以外情報を残せない。

# 状況

## Excelファイル

* 今日中（既に定時後）に Excel ファイルから特定の条件を満たすレコードを抽出する。
* Excel ファイルは開ける。
* しかし、フィルタをかけると死ぬ。
* 分割しようと下半分の行を削除すると死ぬ。
* csv 形式で保存はできる。

## ツール

* 使えるスクリプト言語のは最初から入ってる PowerShell V2 のみ
    * 会社のPC {OS : Windows7} はイントラネットのみの接続
    * ソフトウェアのインストールは会社で定められたもののみ、それ以外は不可



# やったこと

1. Excel ファイルを開いて csv 形式で保存する。
    * 下記 URL を参考にして、PowerShell で csv 化しても良いかも？
    * <http://kurohuku.blogspot.jp/2012/06/powershellexcelcsv.html>

2. 適当なテキストエディタで csv ファイルの文字コードを UTF-8 にする。
    * PowerShell で文字コードを変更してもOK
    * `gc hoge.csv -Encoding String | sc hoge.utf8.csv -Encoding UTF8`
    * <http://qiita.com/kurukurupapa@github/items/74518fad687332c3c09b>

3. ヘッダをいい感じに調整する
     * セルの結合がされているとメンドイ

4. csv ファイルにフィルタをかけて保存
    * `ipcsv hoge.utf8.csv | ?{$_.フィルタをかけたい項目名 -match "フィルタとなる正規表現"} | epcsv hoge.filter.utf8.csv -Encoding UTF8 -NoTypeInformation`
    * <http://news.mynavi.jp/column/powershell/011/>

5. csv ファイルを Excel で開いてよしなにする。
arduinoで大気圧センサー

オークションで手に入れた、BMP085をarduino unoにつないで見ました。
##写真
![MVC-018S.JPG](https://qiita-image-store.s3.amazonaws.com/0/18104/2668bdde-7054-cd17-b03d-80021fd11fe8.jpeg)

##ハイパーターミナル
![bmp085.PNG](https://qiita-image-store.s3.amazonaws.com/0/18104/ea72d85f-a3d2-eef8-d206-1e85170ed23d.png)

##ライブラリー
https://github.com/ohisama/Bmp085
##サンプルコード
```
#include <Wire.h>
#include <Bmp085.h>

Bmp085 dps = Bmp085();
long Temperature = 0, Pressure = 0, Altitude = 0;
void setup(void)
{
	pinMode(13, OUTPUT);
	Serial.begin(9600);
	delay(1000);
	dps.init();
	showall();
	Serial.println("Registers dump");
	dumpRegisters();
	Serial.println("Calibration data");
	dps.dumpCalData();
	delay(5000);
}
void loop(void)
{
	dps.getTemperature(&Temperature);
	dps.getPressure(&Pressure);
	dps.getAltitude(&Altitude);
	Serial.print("Temp(C): ");
	Serial.print(Temperature);
	Serial.print(" Alt(cm): ");
	Serial.print(Altitude);
	Serial.print(" Pressure(Pa): ");
	Serial.println(Pressure);
	digitalWrite(13, HIGH);
	delay(1000);
	digitalWrite(13, LOW);
	delay(1000);
}
void showall(void)
{ 
	Serial.println("Current Bmp085 settings");
	Serial.print("device address = 0x");
	Serial.println(dps.getDevAddr(), HEX);
	Serial.print("Mode = ");
	switch (dps.getMode())
	{
	case MODE_ULTRA_LOW_POWER:
		Serial.println("MODE_ULTRA_LOW_POWER");
	break;
	case MODE_STANDARD:
		Serial.println("MODE_STANDARD");
	break;
	case MODE_HIGHRES:
		Serial.println("MODE_HIGHRES");
	break;
	case MODE_ULTRA_HIGHRES:
		Serial.println("MODE_ULTRA_HIGHRES");
	break;
	}
}
void dumpRegisters()
{
	byte ValidRegisterAddr[] = {
		0xAA,
		0xAB,
		0xAC,
		0xAD,
		0xAE,
		0xAF,
		0xB0,
		0xB1,
		0xB2,
		0xB3,
		0xB4,
		0xB5,
		0xB6,
		0xB7,
		0xB8,
		0xB9,
		0xBA,
		0xBB,
		0xBC,
		0xBD,
		0xBE,
		0xBF,
		0xF6,
		0xF7,
		0xF8,
		0xF9
	};
	byte _b, i, totregisters = sizeof(ValidRegisterAddr);
	Serial.println("---dump start---");
	Serial.println("Register address|Register data");
	Serial.println("Reg.address(hex, dec) Reg.data(bin, hex, dec)");
	for (i = 0; i < totregisters; i++)
	{
		Serial.print("0x");
		Serial.print(ValidRegisterAddr[i], HEX);
		Serial.print(", ");
		Serial.print(ValidRegisterAddr[i], DEC);
		Serial.print(", ");
		dps.readmem(ValidRegisterAddr[i], 1, &_b);
		Serial.print("b");
		print_bits(_b);
		Serial.print(", 0x");
		Serial.print(_b,HEX);
		Serial.print(", ");
		Serial.println(_b,DEC);
	}
	Serial.println("---dump end---");
}
void print_bits(byte val)
{
	int i;
	for (i = 7; i >= 0; i--) Serial.print(val >> i & 1, BIN);
}

```
Docker Toolbox付属のVirtualBox5.0.2では動かないので5.0.3を手動で入れること

## Docker Toolboxのインストール

* 参考: [Docker Toolbox for Mac OS X | harasou.github.io](http://harasou.github.io/2015/08/15/Docker-Toolbox/)
* [download](https://www.docker.com/toolbox)

![スクリーンショット 2015-08-22 5.59.02.png](https://qiita-image-store.s3.amazonaws.com/0/25728/5b119d19-2daf-4550-852c-d31b88f1f86b.png)

![スクリーンショット 2015-08-22 5.59.53.png](https://qiita-image-store.s3.amazonaws.com/0/25728/1f61e489-b98b-54e0-3c30-8fb22b4c28f2.png)

## 実行

![スクリーンショット 2015-08-22 6.01.25.png](https://qiita-image-store.s3.amazonaws.com/0/25728/e694a9e5-6b24-bbdb-53e9-9711e73ca5e3.png)

* `/Applications/Docker/Docker Quick Start Terminal`を実行。

## VMの起動に失敗する

![スクリーンショット 2015-08-22 6.01.37.png](https://qiita-image-store.s3.amazonaws.com/0/25728/559067c2-fe8b-1bdf-f2be-4708650386ca.png)

> host is not running

と表示されたらdefaultのVMの起動に失敗している。


* Docker Toolboxに付属している[VirtualBox 5.0.2だと起動に失敗する](https://github.com/docker/machine/issues/1716)ため[Testbuilds](https://www.virtualbox.org/wiki/Testbuilds)をインストール

![スクリーンショット 2015-08-22 6.16.30.png](https://qiita-image-store.s3.amazonaws.com/0/25728/1624505f-4b13-23ed-c07e-07f43b25160e.png)

## 起動した

![スクリーンショット 2015-08-22 6.23.56.png](https://qiita-image-store.s3.amazonaws.com/0/25728/9bd5bb49-a6ef-b20a-df82-729d9c7fc42c.png)

## 困った場合

* ~/.docker と default のVMを削除し、再度`Docker Quick Start Terminal`を実行すればよい。

## VMの停止方法

```bash:停止
docker-machine stop default
```

## VMの起動方法

```bash:
docker-machine start default
docker-machine ssh default
```

## 環境構築

![スクリーンショット 2015-08-22 8.29.00.png](https://qiita-image-store.s3.amazonaws.com/0/25728/40ae71ca-115d-7beb-a727-8fdf09606597.png)

* SHELL に /bin/bash を追加しておくと、EXECボタンを押した時に bashで起動してくれる。
scp時に.bashrc内プログラムを実行させないように配慮する

## 問題点

```bash:~/.bashrc
bind -x '"\C-f": find'
bind -x '"\C-y": yes "進捗どうですか？"'
bind -x '"\C-t": tmux'
bind -x '"\C-v": vim'
```

こういう記述をしていた場合、他のサーバから`scp`してきた時以下エラーが吐かれつつscp成功する。

> 1 行: bind: 警告: 行編集が有効になっていません
> 2 行: bind: 警告: 行編集が有効になっていません
> 3 行: bind: 警告: 行編集が有効になっていません
> 4 行: bind: 警告: 行編集が有効になっていません


## 気持ち悪いので対策

```diff:~/.bashrc
+ # scp時、「bind: 警告: 行編集が有効になっていません」対策
+ if [ -z "$PS1" ]; then
+     return;
+ fi

  bind -x '"\C-f": find'
  bind -x '"\C-y": yes "進捗どうですか？"'
  bind -x '"\C-t": tmux'
  bind -x '"\C-v": vim'
```

どうも全部読み込むようなので、早めにreturnしておくと良い。
これでscp時に警告が出なくなる。
Golang1.5で試験追加になったvendoringの使い方

やっと標準機能としてvendorを使う処理がついかに！！

```
$ tree -L 4 .
.
├── main.go
└── vendor
    └── github.com
        └── zenazn
            └── goji
```

というディレクトリ構成（もう他のツール類で見覚えあるよね？）

今までだったら

```
$ godeps run main.go
$ godo main.go
```

とかGOPATHにvendorを追加したりとかだったけどこれからは！

```
$ GO15VENDOREXPERIMENT=1 go run main.go
```

これで出来ます！そうです！godepとかの時よりキータイプが増えます！！  
オプションにしてくれよ...

まぁでもコレで配布だったり、CIだったりでgo getしてな！とかなくなるのでまぁ少しは便利になるかな

問題のfetchは、、提供されてません。
これからかな？

http://shinofara.hateblo.jp/entry/2015/08/22/034824
Perlのsort関数まとめ

Perlのsort関数を逆引き式でまとめてみます

# 辞書順の昇順
`sort @LIST;` または `sort {$a cmp $b} @LIST;`
## 例
### 文字列
```
my @data = qw(b a ab aa bc bb B A AB BA);

print "Case1: ", join(", ", sort @data), "\n";
print "Case2: ", join(", ", sort {$a cmp $b} @data), "\n";
```
#### 実行結果
```
Case1: A, AB, B, BA, a, aa, ab, b, bb, bc
Case2: A, AB, B, BA, a, aa, ab, b, bb, bc
```
大文字、小文字は区別される。

### 数列
```
my @nums = qw(100 2 1 10 11 12);

print "Case3: ", join(", ", sort @nums), "\n";
print "Case4: ", join(", ", sort {$a cmp $b} @nums), "\n";
```
#### 実行結果
```
Case3: 1, 10, 100, 11, 12, 2
Case4: 1, 10, 100, 11, 12, 2
```

# 辞書順の昇順(大文字、小文字を区別しない)
`sort {fc($a) cmp fc($b)} @LIST;`
## 例
### 文字列
```
my @data = qw(b a ab aa bc bb B A AB BA);
print "Case5: ", join(", ", sort {fc($a) cmp fc($b)} @data), "\n";
```
#### 実行結果
```
Case5: a, A, aa, ab, AB, b, B, BA, bb, bc
```
大文字、小文字は区別されない。

# 辞書順の降順
`sort {$b cmp $a} @LIST;`
## 例
辞書順の昇順を参考にしてください。

# 辞書順の降順(大文字、小文字を区別しない)
`sort {fc($b) cmp fc($a)} @LIST;`
## 例
辞書順の昇順(大文字、小文字を区別しない)を参考にしてください。

# 数値の昇順
`sort {$a <=> $b} @LIST;`
## 例
### 文字列
```
my @data = qw(b a ab aa bc bb B A AB BA);
print "Case6: ", join(", ", sort {$a <=> $b} @data), "\n";
```
#### 実行結果
```
Case6: b, a, ab, aa, bc, bb, B, A, AB, BA
```
比較できないため変わらない。

### 数列
```
my @nums = qw(100 2 1 10 11 12);
print "Case7: ", join(", ", sort {$a <=> $b} @nums), "\n";
```
#### 実行結果
```
Case7: 1, 2, 10, 11, 12, 100
```

# 数値の降順
`sort {$b <=> $a} @LIST;`
## 例
数値の昇順を参考にしてください。
rbenvでRubyのバージョンアップをする(for Mac)

# rbenvでrubyバージョン2.7.0にする

##新しいバージョンのインストール
###ruby-buildを最新にする
```
$ brew update
$ brew upgrade rbenv ruby-build
```

###インストール可能なリストを表示する
```
$ rbenv install -l
```

### **ruby-buildが最新なのに、インストール可能なリストに新しいバージョンが表示されない場合**
```
$ cd ~/.rbenv/plugins/ruby-build
$ git pull
```

###新しいRubyバージョンのインストール
```
$ rbenv install 2.7.0
```

###インストール済みのrbenvを確認する
```
$ rbenv versions
```



##以下をプロジェクトのルートディレクトリで行う
###バージョンアップをする
```
$rbenv local 2.7.0
```

###bundlerのインストール
```
$ gem update bundler
$ gem install bundler
```
###gem 再インストール
```
$ bundle install
```
Elixirで"1時間以内に解けなければ(ry"をやってみた


[Scala版](http://qiita.com/modal_soul/items/b1b75462f8b080a9eec6)の焼き直しです。
Elixirっぽさがでているかどうかは微妙。

# 問題2

```Problem2.ex
defmodule Problem2 do
	def mutually_list(a, b) do
		Enum.zip(a,b) |> Enum.flat_map(fn {x,y} -> [x,y] end)
	end
end

```

# 問題3

```Problem3.ex
defmodule Problem3 do
	def fib do
		Stream.unfold({0, 1}, fn {a,b} -> {a , {b, a + b}} end)
		|> Enum.take(100)
	end
end
```

# 問題4

```Problem4.ex
defmodule Problem4 do
    def permutations([]), do: [[]]
    def permutations(list) do
        for h <- list, t <- permutations(list -- [h]), do: [h | t]
    end

    def max(list) do
        permutations(list) 
        |> Enum.map(fn p -> Enum.map(p, fn i -> Integer.to_string(i) end) |> List.to_string end) 
        |> Enum.max
    end
end
```

# 問題5

```Problem5.ex
defmodule Problem5 do
	def calc(str, acc) do
		case {Regex.run(~r/(^[1-9]+)(.*)/, str), Regex.run(~r/([+-])([1-9]+)(.*)/, str)} do
			{[_, n, last], _} -> calc(last, acc + String.to_integer(n))
			{_, [_, "+", n, last]} -> calc(last, acc + String.to_integer(n))
			{_, [_, "-", n, last]} -> calc(last, acc - String.to_integer(n))
			_ -> acc
		end
	end
		
	def comb do
		Enum.to_list(2..9)
		|> List.foldl(["1"], fn (x, acc) -> Enum.flat_map(acc, fn n -> ["#{n}#{x}", "#{n}+#{x}", "#{n}-#{x}"] end) end)
	end
	
	def find do
		Enum.filter(comb, fn str -> calc(str, 0) == 100 end)
	end
end

```
xinetd

<h2>設定</h2>
・設定ファイルが2種類ある
　-全体的な設定を、/etc/xinetd.confで行う
　-サービスごとの設定は、別途設定ファイルに記述して、/etc/xinetd.dディレクトリに格納する


```:/etc/xinetd.conf
defaults
 {
	log_type        = stream [ログの出力方法]
	log_on_failure  = HOST [接続拒否時に記録するログの内容]
	log_on_success  = PID HOST DURATION EXIT [接続許可した時に記録するログの内容]
	cps             = 50 10 [1秒間の最大のコネクションすると限度に達した時のサービス休止秒数]
	instance        = 50 [各サービスの最大のデーモン数]
}

includedir /etc/xinetd.d [設定ファイルを格納するディレクトリ]

```

```:/etc/xinetd.d/rsync
service rsync
{
	disable	        = no [サービスを有効にする]
	flags           = IPv6
	socket_type     = stream [TCPならstream, UDPならdgram]
	wait            = no [ウェイトタイム]
	user            = root [サービスを実行するユーザ]
	server          = /usr/bin/rsync [サーバプログラムのパス]
	server_args     = --daemon [引数]
	log_on_failure  += USERID [接続拒否時に記録するログの内容]
}
```

<table>
<tr>
<th>パラメータ</th><th>説明</th>
</tr>
<tr>
<td>disable</td><td>サービスの有効/無効 </td>
</tr>
<tr>
<td>socket_type</td><td>通信タイプ(TCPは、tream, UDPはdgram)</td>
</tr>
<tr>
<td>wait</td><td>ウェイトタイム</td>
</tr>
<tr>
<td>user</td><td>サービスを実行するユーザ名</td>
</tr>
<tr>
<td>server</td><td>サーバプログラム(デーモン)へのフルパス</td>
</tr>
<tr>
<td>server_args</td><td>サーバプログラム（デーモン)に渡す引数</td>
</tr>
<tr>
<td>log_on_failure</td><td>接続を拒否した時に、ログに記述する内容</td>
</tr>
<tr>
<td>nice</td><td>実行優先度</td>
</tr>
<tr>
<td>only_from</td><td>接続を許可する接続元</td>
</tr>
<tr>
<td>no_access</td><td>接続を拒否する接続元</td>
</tr>
<tr>
<td>access_times</td><td>アクセスを許可する時間帯</td>
</tr>

</table>



*再起動を忘れずに
・/etc/init.d/xinetd restart
すぐ死んでしまうgulp watchを蘇らせるスクリプト書いた

gulp watchはすぐ死んでしまう上に例外がキャッチできないプラグインがいたりして、とてもイライラします。
なので、死んでもすぐゾンビのように復活させるPythonスクリプトを書きました

```py:zombie.py
#!/usr/bin/env python
# -*- codint: utf-8 -*-

import sys
import signal
import subprocess

def rite(silent):
    print("start rite of gulp watch be zombie")
    print("if you want stop this program, Ctrl+C")
    cmd = "gulp watch"
    while True:
        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        for line in iter(p.stdout.readline, b''):
            print(line.rstrip())
        if not silent:
            print("\a")
        print("\ngulp watch is dead. but revive soon.\n")

def signalHandler(signal, frame):
    print("\ngulp zombie killed")
    sys.exit(0)

if __name__ == '__main__':
    signal.signal(signal.SIGINT, signalHandler)
    try:
        sys.argv.index("-s")
        rite(True)
    except ValueError:
        rite(False)
```

これをgulpfile.jsと同じところに突っ込んで

```
python zombie.py
```

とすればgulp watchが死んでもゾンビのごとく復活します。
ちなみに通常ではビープ音で死亡を知らせてくれますが、

```
python zombie.py -s
```

としてやれば、静かにする事もできます。
通常のコマンド同様Ctrl+Cでこのゾンビを抹殺する事もできます。
[Gist](https://gist.github.com/iwamatsu0430/f2dc37e0aa610f4efa45)
雑にこないだのハッカソンで投げたクエリ晒す

# 晒すクエリ

http://sparql.odp.jig.jp/ にて、下記のようなクエリを投げました

```
PREFIX jrrk: <http://purl.org/jrrk#> 
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
PREFIX schema: <http://schema.org/> 
PREFIX geo:<http://www.w3.org/2003/01/geo/wgs84_pos#> 
SELECT DISTINCT ?lat ?lng ?image_url ?name { 
  ?target_rdf rdf:type jrrk:CivicPOI; 
              geo:lat ?lat;  
              geo:long ?lng; 
              schema:image ?image_url;
              rdfs:label ?name
}
```

帰ってきたjsonは下記です

```
{
  "head": {
    "vars": [ "lat" , "lng" , "image_url" , "name" ]
  } ,
  "results": {
    "bindings": [
      {
        "lat": { "datatype": "http://www.w3.org/2001/XMLSchema#float" , "type": "typed-literal" , "value": "35.970872" } ,
        "lng": { "datatype": "http://www.w3.org/2001/XMLSchema#float" , "type": "typed-literal" , "value": "136.176053" } ,
        "image_url": { "type": "uri" , "value": "http://www3.city.sabae.fukui.jp/xml/sabakan/simage/t_gourmet_410.jpg" } ,
        "name": { "type": "literal" , "xml:lang": "ja" , "value": "豚ちんかん" }
      } ,
      {
        "lat": { "datatype": "http://www.w3.org/2001/XMLSchema#float" , "type": "typed-literal" , "value": "35.94276" } ,
        "lng": { "datatype": "http://www.w3.org/2001/XMLSchema#float" , "type": "typed-literal" , "value": "136.193016" } ,
        "image_url": { "type": "uri" , "value": "http://www3.city.sabae.fukui.jp/xml/sabakan/simage/g-244.gif" } ,
        "name": { "type": "literal" , "xml:lang": "ja" , "value": "やきとりの名門　秋吉　鯖江店" }
      } ,
      // ...
    ]
  }
}
```

# 何やっているの??

Open Data Platform (odp)のSPARQLエンドポイントから観光地の名前と観光地紹介画像のURL、観光地の緯度経度を取得しています。

## 解説してよ

~~今日もう眠いので~~また今度解説をするような記事を書こうかと思います。
vimでchangelog


1) シェルで以下を実行

```bash
vim .vimrc
```

2) .vimrcに以下を追記

```.vimrc
let g:changelog_timeformat="%Y-%m-%d"
let g:changelog_username="hoge<hoge@hoge.co.jp>"
```
3) シェルで以下を実行

```bash
vim changelog
```

4) あとはノーマルモードで¥oを入力すると、こんな感じになる。

```changelog
2015-08-22  hoge <hoge@hoge.co.jp>

        * test
        * 

```
Nginx で SSL証明書 の設定時のトラブルシューティング方法

## 背景

* Nginx で HTTPS 通信するため、証明書関連の設定で時間を要した
* まとまったドキュメントが見つからなかったので、ノウハウをまとめてみた。

## 設定項目

Nginx の SSL 証明書関連で大切なのは次の設定。

```
        ssl on;
        ssl_certificate /etc/ssl/certs/www.example.com.chained.cert;
        ssl_certificate_key /etc/ssl/certs/www.example.com.key;
```

Nginx から、指定したファイルがアクセス可能かどうか、権限を確認する。
また、ファイル名が誤っていないか、確認する。

## 作成した証明書の確認

特に下記のコマンドは有用

### 秘密鍵の確認

```
$ openssl rsa -in /etc/ssl/certs/www.example.com.key -check
RSA key ok
writing RSA key
-----BEGIN RSA PRIVATE KEY-----
MIIEp ．．．
中略
-----END RSA PRIVATE KEY-----
```

### 公開鍵の確認

```
$ openssl x509 -in /etc/ssl/certs/www.example.com.cert -text -noout
Certificate:
    Data:
        Version
（略）
```

### 中間証明書の確認

GoDaddy の証明書を使っているので、サイトから中間証明書を事前にダウンロードしておく。
https://certs.godaddy.com/repository/

ダウンロードした中間証明書が正しいか確認する。

```
$ openssl x509 -in gd_bundle-g2-g1.crt  -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 7 (0x7)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2
        Validity
            Not Before: May  3 07:00:00 2011 GMT
            Not After : May  3 07:00:00 2031 GMT
        Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., OU=http://certs.godaddy.com/repository/, CN=Go Daddy Secure Certificate Authority - G2
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
（略）
```

### 秘密鍵、公開鍵が対応しているかの確認

#### 秘密鍵の modulus を表示
```sh
$ openssl rsa  -in /etc/ssl/certs/www.example.com.key  -modulus -noout
Modulus=D3DF880A(snip)
```

#### 公開鍵の modulus を表示
```
$ openssl x509  -in /etc/ssl/certs/www.example.com.cert -noout -modulus
Modulus=D3DF880A(snip)
```

秘密鍵と公開鍵の modulus が同じことを確認する。

### 公開鍵と中間証明書が対応しているかの確認

```sh
$ openssl x509 -issuer_hash -noout -in /etc/ssl/certs/www.example.com.cert
85cf5865
```

```sh
$ openssl x509 -subject_hash -noout -in gd_bundle-g2-g1.crt  -text -noout
85cf5865
```

ハッシュ値が同じことを確認する。

### 鍵の生成

Nginx では中間証明書を含めて、１つのファイルにする必要がある。

```
$ cat www.example.com.cert gd_bundle-g2-g1.crt > www.example.com.chained.cert
```

## Nginx が SSL 有効かを確認

```
$ nginx -V
```

下記の表示を確認する。
```
TLS SNI support enabled
（前略）--with-http_ssl_module　（略）
```

## SSL 通信の確認

Nginx の設定が正しいどうか、openssl コマンドで接続して、確認できる。

```
$ openssl s_client -connect www.example.com:443 -showcerts
（略）
    Verify return code: 21 (unable to verify the first certificate)
```
などと表示されれば、正しく設定できていない。
中間証明書などを確認する。

```
$ openssl s_client -connect www.example.com:443 -showcerts
（略）
  Verify return code: 0 (ok)
```

と表示されれば、成功である。

私の場合は、`gd_bundle-g2-g1.crt` だとうまくいったのだが、
それではないものをベースに最初試していたため、ハマってしまっていた。

## CloudFront 経由（SNI）で正しく動作するかの確認

CloudFront を経由するときなど、SNI を利用するときは、 -servername オプション付きで実行する。

```
$ openssl s_client -connect xxxxxxxxxxx.cloudfront.net:443 -servername www.example.com -showcerts
（略）
    Verify return code: 0 (ok)
```
最後に `    Verify return code: 0 (ok)` が表示されれば成功である。
Intel INDE OpenCV

以下の記事を見つけた。

PCでのOpenCVを高い処理速度で実行させたい人は読むべき記事に思える。

Profiling the Intel® INDE OpenCV Applications
https://software.intel.com/en-us/articles/profiling-intel-inde-opencv


以下は、いいプロファイル環境が欲しいなと思っていた私の雑感である。
そんなどうでもよい雑感を読んでいる暇があったら、 Intel® INDE OpenCV Applicationsが何物であるのか、使っている人の感想を知りたいと思う。

リンク先のページにあるグラフは、マルチスレッドやGPGPUを使っているOpenCVユーザーにとってとても有益な情報を与えてくれるように思う。

以下　雑感

OpenCVを利用したプログラムでのプロファイリングは、
OpenCVのビルドの中身で動作が著しく異なってくるため、
自信のあるプロファイリングが必ずしも容易ではないことを感じている。

マルチスレッドであったり、SIMD命令があったり、GPGPUがあったりする。
プロファイリングを取得するためのコードが入ることによって
それ以前と動作の状況が異なってしまうことで、
本当に目的の解析になっているのかを自信を持って知ることは
容易ではない。

Pythonからcv2.pydファイルを解してOpenCVを利用していると
Python自体のプロファイラの中で計測している時間と
計測されていない時間との範囲がどうなっているのか
自分の理解が及んでいないことを深く感じる。
PostgreSQL 9.5新機能 psqlからのAsciiDoc形式出力を試してみた

PostgreSQL 9.5で実装される小ネタの紹介です。

PostgreSQLのクライアントであるpsqlの出力結果をAsciiDoc形式で出せるようになりました。

今回使ったバージョンは、つい最近リリースされたPostgreSQL 9.5alpa2です。


# AsciiDocとは

AsciiDocとはMarkdownのようなマークアップ言語で、HTMLやPDF、ePUBなどの多様なフォーマットに変換することができます。

軽量TeXのような印象です。
実際AsciiDocをインストールする際にTexLiveがインストールされているので、内部的にはTeXを利用しているようです。

細かい記法とか全然わかっていません(^_^;;)
今回は、私が記法を知らなくてもpsqlさんが出力してくれるので見逃してください。

# AsciiDocのインストール方法 @ CentOS7

yumでインストールできます。便利ですねー

```
# yum install asciidoc asciidoc-doc asciidoc-latex
```

TeX関連で300弱のパッケージがインストールされるので少し重たいです。

また、AsciiDocからPDFを作成するためにApache FOPもインストールします。

```
# yum install fop
```

# psqlでのAsciidoc出力方法

`\pset`メタコマンドでformatオプションを指定します。

```
postgres=# \pset format asciidoc
Output format is asciidoc.
```
これで以降のクエリ結果がAsciiDoc形式で出力されます。

適当にテーブルを作ってクエリ結果を出してみます。

```
postgres=# CREATE TABLE foo (a int PRIMARY KEY, b text);
CREATE TABLE
postgres=# INSERT INTO foo VALUES ( generate_series(1,100), 'inserted');
INSERT 0 100
ostgres=# SELECT * FROM foo WHERE mod(a,7) = 3;

[options="header",cols=">l,<l",frame="none"]
|====
^l|a ^l|b
|3 |inserted
|10 |inserted
|17 |inserted
|24 |inserted
|31 |inserted
|38 |inserted
|45 |inserted
|52 |inserted
|59 |inserted
|66 |inserted
|73 |inserted
|80 |inserted
|87 |inserted
|94 |inserted
|====

....
(14 rows)
....
```

（´･∀･`）ﾍｰ


このままだと私がよく分からないので、HTMLとPDFに変換してみます。
そのために、クエリ結果をファイルに保存しておきます。
psqlの`\o`メタコマンドを使って出力先ファイルを指定します。

```
postgres=# \o /home/postgres/output.adoc
postgres=# SELECT * FROM foo WHERE mod(a,7) = 3;
```

これでOK。

## AsciiDocからHTMLへの変換

```
$ asciidoc output.adoc
```

output.htmlというファイルができているのでブラウザで見てみると...

![HTML変換結果.png](https://qiita-image-store.s3.amazonaws.com/0/82034/28e6a2a8-b05f-b931-4f19-9d91077f430e.png)

( ・∀・)つ〃∩ ﾍｪｰﾍｪｰﾍｪｰ

# AsciiDocからPDFへの変換

```
$ a2x output.adoc
```

HTMLの時よりも少し時間がかかって、output.pdfというファイルが出来ます。
これをPDFビューアで見ると...


![PDF変換結果1.png](https://qiita-image-store.s3.amazonaws.com/0/82034/7f06818a-da77-7d6c-0fd5-d26558be7796.png)


ええっ、変更履歴！？

![PDF変換結果2.png](https://qiita-image-store.s3.amazonaws.com/0/82034/a35b2f9e-6b54-ca2a-ec97-96d95aa26061.png)

さらに目次？！

![PDF変換結果3.png](https://qiita-image-store.s3.amazonaws.com/0/82034/2fb4ce19-09c0-b247-1d39-102114b32070.png)

w(￣Д￣;)wｽｹﾞー

# まとめ

psqlからのAsiiDoc出力、予想以上に使えそうです。
技術テキスト書いているときに役立ちそうですね。
Dell OMSA (OpenManage Server Administrator) をUbuntu 14.04にインストール

Ubuntu 14.04をインストールしているDell社製のサーバに、管理ツールのOMSAを入れる方法。OMSAを入れるとウェブブラウザからサーバの状態監視やRAID設定の変更などができる。

http://linux.dell.com/repo/community/ubuntu/ に専用のリポジトリがあるので、aptで導入できるが、ちょっと変更しないとログインできない。

1. aptにsourceを追加する。
`echo 'deb http://linux.dell.com/repo/community/ubuntu trusty openmanage' | sudo tee -a /etc/apt/sources.list.d/linux.dell.com.sources.list`
2. リポジトリの鍵を登録する。
`gpg --keyserver pool.sks-keyservers.net --recv-key 1285491434D8786F`
`gpg -a --export 1285491434D8786F | sudo apt-key add - `
3. aptを更新する。
`sudo apt-get update`
4. パッケージをインストールする。個別でも良いが、全部入れれば良さそう。
`sudo apt-get install srvadmin-all`
5. 起動させる前に、/etc/init.d/dsm_om_connsvc の以下の部分を変更する。変更しないと、ウェブUIにログインページは表示されるけど、ログインするとサービスが落ちてしまう。
`START_DAEMON ${PROGRAM_DAEMON} -run`
を
`START_DAEMON ${PROGRAM_DAEMON} -clrun >/dev/null 2>&1 &`
に書き換える。
6. ウェブUIにroot以外でアクセスしたい場合は、/opt/dell/srvadmin/etc/omarolemap に以下のようにして管理ユーザを追加する。
`john     *     Administrator`
7. サービスを起動させる。
`sudo service dataeng start`
`sudo service dsm_om_connsvc start`
8. ブラウザで、サーバの1311ポートにアクセスする。URLは、オレオレSSL認証で、 https://server_ip_or_host:1311/ 。rootでログインできるが、別のログインユーザを使いたい場合は、6でユーザを追加する。

リポジトリのページには、OS起動時にサービスを起動させる方法なども載っている。

参考ページ
* [OMSA 5.5 on Ubuntu 8.10 (AMD64)](http://lists.us.dell.com/pipermail/linux-poweredge/2009-March/038766.html)
Android4系で不具合が出たら一度これ試してみて

個人でXperiaZを使っていてアプリを作ったりもするんですが、ある時から不具合が出るようになった。
それもボロボロと。

- GPSが全くと言っていいほど認識されない。
- USBで接続しようとすると高速でデバッグモードになって充電できない。それどころか落ちる。
- ジャイロセンサーが常に回転していて目が回りそう。

そんな時にふと試したことがあるんですが、一気に解消された。
アプリ開発者(というよりデバッグモード有効にしてゴニョゴニョしたことある人)は一度試してみては？

**[設定]→[開発者向けオプション]→[USBデバッグ]チェック解除**
その後再びチェックをいれる。

これで僕のXperiaZは延命しました。よろしかったらぜひ。
Rubyのループを減速させる

ふつう、プログラム中のループは全力で回しますが、ときに減速させたくなることもあります。

# 背景
たとえば外部APIを使う場合など、一定時間内にAPIを叩ける回数が決まっていることがあります。また、そうでなくてもWebスクレイピングなどは速度を手加減してやらないと迷惑です。

もちろん、「1秒間に100アクセスできるAPIを、使い切らないギリギリぐらいのペースで仕事をしたい」というような、ある程度のスケールがあるような用事であれば、Sidekiqを立てて複数スレッドをスケジューリングするなど、きっちりした仕組みを構築する必要があるでしょう。

ただ、逆に「1回あたり100ミリ秒もかからない仕事だけど、3秒に1回のペースでしたい」というような状況であれば、メインスレッド1本で処理をさせれば充分ですし、外部の仕組みを立てるには大げさすぎます。

# 意外と簡単な別スレッド
ややこしい印象のあるスレッドですが、Rubyでは1行で作れてしまいます。

```rb:Thread.new
t = Thread.new { 実行するコード }
```
もちろん、スレッドを作りっぱなしでは役に立ちませんし、スレッドが外部と連携して動作しようとすれば一気に複雑化します。とはいえ、今回の「時間待ち」程度であれば、簡単に片付きます。

# 目的のコード
```rb
some_collection.each do |obj|
  t = Thread.new { sleep 3 }
  # objを使ったメイン処理
  t.join
end
```

まず、メインの処理を行う前に、時間測定用のスレッドを立てて、バックで動かしておきます。そして、最後に`.join`すると、「スレッドの終了まで待つ」という動作になりますので、指定時間が経過するまでループが進まなくなります。なお、すでに終了したスレッドに`.join`しても特にエラーとなることはなく、呼び出し側にすぐ戻ります。

# スレッドへの引数
状況によって待機時間を変えたい場合、スレッドに値を渡す必要があります。ただし、無遠慮に外側の変数を渡してしまうと、内側のスレッドが読むタイミングでは値が変化している、ということがありえます。そこで、スレッド開始時に引数として渡す必要があります。

```rb:thread-parameter.rb
sleep_time = obj.some_method
t = Thread.new(sleep_time) { |st| sleep st }
```

なお、両スレッドでオブジェクトとして共有されるので、ミュータブルなものを渡す場合には注意が必要です（いミュータブルな、数値やシンボルでは特に問題ないですが）。