OmniAICreator/Qiita-1.07M huggingface dataset:
MXMLポップアップ データの受け渡し

「mx.managers.PopUpManager」を利用して「mx.containers.TitleWindow」をポップアップするときにデータを渡す方法を紹介します。
TextInputに入力した内容をTilteWindowのTextに表示します。

```mxml:sample1.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="600" height="400">
	<mx:Script>
		<![CDATA[
			import mx.containers.TitleWindow;
			import mx.managers.PopUpManager;
			private function popup():void{
				var tw:titleWindow = new titleWindow();
				mx.managers.PopUpManager.addPopUp(tw,this,true);
				mx.managers.PopUpManager.centerPopUp(tw);
				tw.init(myTextInput.text);			
			}
		]]>
	</mx:Script>
	<mx:TextInput x="10" y="10" id="myTextInput"/>
	<mx:Button x="178" y="10" label="ボタン" click="popup()"/>
</mx:Application>
```

```mxml:sample2.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="226" height="128" showCloseButton="true" close="close()">
	<mx:Script>
		<![CDATA[
			import mx.managers.PopUpManager;
			public function init(str:String):void{
				myText.text = str;
			}
			private function close():void{
				mx.managers.PopUpManager.removePopUp(this);
			}
		]]>
	</mx:Script>
	<mx:Text x="10" y="10" text="文字" width="186" id="myText" />
</mx:TitleWindow>
```

次にTitleWindowのTextInputに入力した内容を親のTextに渡す方法を紹介します。
ポイントは、TilteWindowをポップアップ表示した後に、TilteWindowが閉じられるのを監視するためにaddEventListenerを追加します。

```mxml:sample3.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="popup()" width="600" height="400">
	<mx:Script>
		<![CDATA[
			import mx.containers.TitleWindow;
			import mx.managers.PopUpManager;
			private function popup():void{
				var tw:titleWindow = new titleWindow();
				mx.managers.PopUpManager.addPopUp(tw,this,true);
				mx.managers.PopUpManager.centerPopUp(tw);
				tw.addEventListener(Event.REMOVED,twClose);
			}
			private function twClose(e:Event):void{
				var tw:titleWindow = e.target as titleWindow;
				myText.text = tw.myTextInput.text;
			}
		]]>
	</mx:Script>
	<mx:Text x="10" y="10" id="myText"/>
	<mx:Button x="178" y="10" label="ボタン" click="popup()"/>
</mx:Application>
```

```mxml:sample4.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="226" height="128" showCloseButton="true" close="close()">
	<mx:Script>
		<![CDATA[
			import mx.managers.PopUpManager;
			private function close():void{
				mx.managers.PopUpManager.removePopUp(this);
			}
		]]>
	</mx:Script>
	<mx:TextInput x="10" y="10" text="" width="122" id="myTextInput" />
	<mx:Button x="140" y="8" label="OK" click="close()"/>
</mx:TitleWindow>
```

***
この記事は、以前ブログで公開していた記事、内容を再編集したものです。
ActionScript 1.0/2.0/3.0とFlex 3の内容が中心です。
FuelPHPでMySQLにインデックスを追加するタスク

マイグレーションでも追加できるけど、運用後にインデックスだけメンテナンスしたい場合に不便なので、インデックス関係だけタスクにまとめてしまおうということ。

# タスクを作成

[ダウンロード(Gist)](https://gist.github.com/goosys/01e588dbc15235d4a908)

```php:fuel/app/tasks/migrate_indexes.php
<?php

namespace Fuel\Tasks;

class Migrate_indexes
{
	
	public static function run()
	{
	}
	
	public static function up()
	{
		static::_up('topics', array('id'), 'idx_id');
		static::_up('topics', array('deleted_at'), 'idx_dl');
		static::_up('topics', array('id','deleted_at'), 'idx_id_dl');
		static::_up('topics', array('deleted_at','created_at'), 'idx_dl_cr');
		static::_up('topics', array('created_at'), 'idx_cr');
		
		static::_up('comments', array('id'), 'idx_id');
		static::_up('comments', array('deleted_at'), 'idx_dl');
		static::_up('comments', array('id','deleted_at'), 'idx_id_dl');
		static::_up('comments', array('deleted_at','created_at'), 'idx_dl_cr');
	}
	
	public static function down()
	{
		static::_down('topics', 'idx_id');
		static::_down('topics', 'idx_dl');
		static::_down('topics', 'idx_id_dl');
		static::_down('topics', 'idx_dl_cr');
		static::_down('topics', 'idx_cr');
		
		static::_down('comments', 'idx_id');
		static::_down('comments', 'idx_dl');
		static::_down('comments', 'idx_dl_cr');
		static::_down('comments', 'idx_cr');
	}
	
	protected static function _up($table, $index_columns, $index_name)
	{
		try{
			\DBUtil::create_index($table, $index_columns, $index_name);
			\Cli::write(\Cli::color('Created index: '.$table. ' : '. implode(',',$index_columns). ' : '. $index_name, 'green'));
		}catch( \Fuel\Core\Database_Exception $e ){
		}
	}
	
	protected static function _down($table, $index_name)
	{
		try{
			\DBUtil::drop_index($table, $index_name);
			\Cli::write(\Cli::color('Dropped index: '.$table. ' : '. $index_name, 'green'));
		}catch( \Fuel\Core\Database_Exception $e ){
		}
	}
}
```

# 実行
## インデックスを追加

```shell-session
php oil r migrate_indexes:up
```

## インデックスを削除

```shell-session
php oil r migrate_indexes:down
```
ActionScriptからデータをポストする

ActionScriptからデータをポストします。
ポイントは、URLRequestMethod.POSTと、変数を転送するためのURLVariables。

```as3:post.as
private function postData():void{
  var url:String = "post.php";
  var urlReq:URLRequest = new URLRequest(url);
  
  // POSTを指定する
  urlReq.method = URLRequestMethod.POST;

  // アプリケーションとサーバーの間で変数を転送する
  var urlVar:URLVariables = new URLVariables();
  urlVar.email = myTextInput.text;

  urlReq.data = urlVar;
  var urlLoader:URLLoader = new URLLoader(urlReq);
  urlLoader.addEventListener(Event.COMPLETE,completeHandler);
}

private function completeHandler(e:Event):void{
  var loader:URLLoader = URLLoader(e.target);
  trace(loader.data); // POSTしたデータを表示する
}
```

データを受信するPHPのコードです。
受信したデータをそのまま表示します。

```php:post.php
<?php
echo $_POST['email'];
?>
```

***
この記事は、以前ブログで公開していた記事、内容を再編集したものです。
ActionScript 1.0/2.0/3.0とFlex 3の内容が中心です。
JSONの解析

XML形式とJSON形式を比較します。

はじめにXML形式を示します。

```xml:news.xml
<data> 
　<news> 
　　<id>0002</id> 
　　<date>2009.03.02</date> 
　　<title>迷ったお年寄り 犬散歩で捜索</title> 
　　<description>毎日欠かさない愛犬の散歩中に、ご近所で目配りしてもらおうという計画だ</description> 
　</news> 
　<news> 
　　<id>0003</id> 
　　<date>2009.03.03</date> 
　　<title>朝にかけ関東甲信で大雪も</title> 
　　<description>気象庁では、交通機関の乱れや路面の凍結などへの注意を呼びかけている</description> 
　</news> 
</data>
```

次にJSON形式を示します。

```json:news.json
[ 
  { 
    "id" : "0002", 
    "date" : "2009.03.02", 
    "title" : "迷ったお年寄り 犬散歩で捜索", 
    "description" : "毎日欠かさない愛犬の散歩中に、ご近所で目配りしてもらおうという計画だ" 
  }, 
  { 
    "id" : "0003", 
    "date" : "2009.03.03", 
    "title" : "朝にかけ関東甲信で大雪も", 
    "description" : "気象庁では、交通機関の乱れや路面の凍結などへの注意を呼びかけている" 
  } 
]
```

次にXML形式とJSON形式の解析方法を比較します。
JSON形式の解析にはAdobeがリリースしているas3corelibというライブラリにあるJSONクラスを利用します。
JSONファイルは文字コードUTF-8、改行コードLFで保存します。

はじめにXML形式の解析です。

```as3:xml.as
var urlReq:URLRequest = new URLRequest("news.xml"); 
var urlLoader:URLLoader = new URLLoader(); 
urlLoader.addEventListener(Event.COMPLETE,completeHandler); 
function completeHandler(e:Event):void{ 
  var xmlList:XMLList = new XMLList(e.target.data); 
  trace(xmlList.news[0].id); //0002 
  trace(xmlList.news[1].title); //朝にかけ関東甲信で大雪も 
}
```

次にJSON形式の解析です。

```as3:json.as
import com.adobe.serialization.json.JSON; 
var urlReq:URLRequest = new URLRequest("news.json"); 
var urlLoader:URLLoader = new URLLoader(); 
urlLoader.addEventListener(Event.COMPLETE,completeHandler); 
function completeHandler(e:Event):void{ 
  var json:String = e.target.data; 
  // 置換処理を行えばCR+LF、CRでも可能
  //json = json.replace(/\r\n|\r/g, '\n');

  var news:Array = JSON.decode(json); //デコード
  trace(news[0].id); //0002 
  trace(news[1].title); //朝にかけ関東甲信で大雪も 
}
```


***
この記事は、以前ブログで公開していた記事、内容を再編集したものです。
ActionScript 1.0/2.0/3.0とFlex 3の内容が中心です。
フォントの取得

フォントの一覧を配列で取得します。

> enumerateFonts(enumerateDeviceFonts:Boolean = false):Array 
[静的] 現在使用可能な埋め込みフォントのリストを提供するかどうかを指定します。

```as3:font.as
Font.enumerateFonts(true).forEach(function(item,arr,index){trace(item.fontName)})
```
これを実行すると以下のようにフォントの名前を表示します。

> Adobe Caslon Pro Bold 
Adobe Caslon Pro 
Adobe Garamond Pro Bold 
Adobe Garamond Pro 
（省略）


***
この記事は、以前ブログで公開していた記事、内容を再編集したものです。
ActionScript 1.0/2.0/3.0とFlex 3の内容が中心です。
誕生日年齢計算

誕生日から年齢を計算します。

PHPで書く場合です。

```php:birthday.php
<?php
　$now = date("Ymd"); 
　$birth = "19800901"; 
　echo floor(($now-$birth)/10000);
?>
```

Flex SDKに含まれるDateFormatterを利用する場合です。

```as3:birthday4flex.mxml
import mx.formatters.DateFormatter; 
var date_fmt:DateFormatter = new DateFormatter(); 
date_fmt.formatString = "YYYYMMDD"; 
var now:Number = Number(date_fmt.format(new Date())); 
var birth:Number = 19800901; 
trace(Math.floor((now-birth)/10000));
```
ActionScript3.0で書く場合です。

```as3:birthday4as.as
var date:Date = new Date(); 
var now:Number = date.getFullYear() + (date.getMonth()+1) * 100 + date.Date(); 
var birth:Number = 19800901; 
trace(Math.floor((now-birth)/10000));
```

***
この記事は、以前ブログで公開していた記事、内容を再編集したものです。
ActionScript 1.0/2.0/3.0とFlex 3の内容が中心です。
浮動小数点数

JavaScriptとActionScript1.0/2.0/3.0の浮動小数点数の精度を比較してみました。
JavaScriptの結果は、IE7、Opera10(Win)、Safari4(Win)で実行したものです。

```js:fpn.js
<script type="text/javascript"> 
<!--
var n = 0; 
for(var i = 0; i < 10; i++){ 
  n += 0.1; 
  document.write(n+"<br />"); 
} 
// --> 
</script>
```

> 0.1 
0.2 
0.30000000000000004 
0.4 
0.5 
0.6 
0.7 
0.7999999999999999 
0.8999999999999999 
0.9999999999999999

```as3:fpn4as3.as
// ActionScript3.0
var n:Number = 0; 
for (var i:Number = 0; i < 10; i++) { 
  n += 0.1; 
  trace(n); 
}
```

> 0.1 
0.2 
0.30000000000000004 
0.4 
0.5 
0.6 
0.7 
0.7999999999999999 
0.8999999999999999 
0.9999999999999999


```as:fpn4as2.as
// ActionScript1.0/2.0
var n = 0; 
for (var i = 0; i < 10; i++) { 
  n += 0.1; 
  trace(n); 
}

```

> 0.1 
0.2 
0.3 
0.4 
0.5 
0.6 
0.7 
0.8 
0.9 
1

***
この記事は、以前ブログで公開していた記事、内容を再編集したものです。
ActionScript 1.0/2.0/3.0とFlex 3の内容が中心です。
FLVファイルの再生

FLVファイルを再生するためには、Video、NetStream、NetConnectionを利用します。

以下のコードではページを表示後、すぐに再生を開始します。

```as3:flv1.as
var video:Video = new Video();
var netStream:NetStream;
var netConnection:NetConnection = new NetConnection();

netConnection.addEventListener(NetStatusEvent.NET_STATUS,netStatusHandler);
netConnection.connect(null);
function netStatusHandler(e:NetStatusEvent):void {
	netStream = new NetStream(netConnection);
	video.attachNetStream(netStream);
	netStream.client = onMetaData();
	netStream.play("../media/sample.flv");
	// 音量調整 
	// SoundTransform(音量,パン); 
	// 音量 0.0(無音)〜1.0(フル) 
	// パン -1.0(左) 0.0(中央) 1.0(右) 
	var transform:SoundTransform = new SoundTransform(0.0, 0);
	var sound:Sound = new Sound();
	netStream.soundTransform = transform;
	addChild(video);
}
function onMetaData():Object{
	return Object;
}
```

このコードをステージをクリックしたら再生を開始するに変更します。
NetStream.play()を実行後、NetStream.pause()を実行し、再生を停止します。
ステージをクリックしたときに再生を再開するためのイベントリスナーを追加します。

```as3:flv2.as
var video:Video = new Video();
var netStream:NetStream;
var netConnection:NetConnection = new NetConnection();
netConnection.addEventListener(NetStatusEvent.NET_STATUS,netStatusHandler);
netConnection.connect(null);
function netStatusHandler(e:NetStatusEvent):void {
	netStream = new NetStream(netConnection);
	video.attachNetStream(netStream);
	netStream.client = onMetaData();
	netStream.play("../media/sample.flv");
	netStream.pause();
	addChild(video);
}
stage.addEventListener(MouseEvent.CLICK,function (e:MouseEvent):void{
	netStream.resume(); //再開 
});
function onMetaData():Object {
	return Object;
}
```

このコードでステージをクリックすると再生を開始するようになりました。
このままでは、NetStream.play()の実行直後にNetStream.pause()を実行するため、ストリームの先頭を表示できません。
これを解決するためにNetStream.play()の直後にNetStream.seek(0.0)を実行し、ストリームの先頭を表示します。

```as3:flv3.as
var video:Video = new Video();
var netStream:NetStream;
var netConnection:NetConnection = new NetConnection();
netConnection.addEventListener(NetStatusEvent.NET_STATUS,netStatusHandler);
netConnection.connect(null);
function netStatusHandler(e:NetStatusEvent):void {
	netStream = new NetStream(netConnection);
	video.attachNetStream(netStream);
	netStream.client = onMetaData();
	netStream.play("../media/sample.flv");
	netStream.seek(0.0);
	netStream.pause();
	addChild(video);
}
stage.addEventListener(MouseEvent.CLICK,function (e:MouseEvent):void{
	netStream.resume(); //再開 
});
function onMetaData():Object {
	return Object;
}
```

***
この記事は、以前ブログで公開していた記事、内容を再編集したものです。
ActionScript 1.0/2.0/3.0とFlex 3の内容が中心です。
SWF同士の通信

SWF同士または、SWFとAdobe AIRとの通信はLocalConnectionクラスで実装可能です。
キーボードから入力されたアルファベットを、もう一方のSWFに送信して表示します。

```as3:send.as
/*
** 送信（アルファベットを送信する）
*/
var sendLC:LocalConnection = new LocalConnection();
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownHandler);
function keyDownHandler(e:KeyboardEvent):void{
	var codeMap:String="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	if(e.keyCode >= 65 && e.keyCode <= 90){
		// キーコードをアルファベットに変換
		var code:String = codeMap.substr(e.keyCode -65,1);
		//接続名（送信・受信で同じ名前にする）
		//メソッド名（受信側で呼び出されるメソッド）
		//パラメータ（メソッドに渡すパラメータ）
		sendLC.send("LC","getMsg",{c:code});
	}
}
```

```as3:receive.as
/*
** 受信（受信したアルファベットを表示する）
*/
var receiveLC:LocalConnection = new LocalConnection();
// 接続名（送信・受信で同じ名前にする）
receiveLC.connect("LC");
receiveLC.client=this;
function getMsg(obj:Object):void{
	tf.text = obj.c;
}
````

***
この記事は、以前ブログで公開していた記事、内容を再編集したものです。
ActionScript 1.0/2.0/3.0とFlex 3の内容が中心です。
不要な文字を取り除く

文字列から不要な文字を取り除くには、split(elimiter:*, limit:Number = 0x7fffffff)でサブストリングの配列に分割してからjoin(sep:*)で結合します。
これを利用するとCSV形式のファイルを読み込んで配列に変換することができます。

```as3:csv.as
/*
** CSV形式のデータを用意する
** 1,taro,A
** 2,hanako,AB
*/
var csv:String = "1,taro,A\n\r2,hanako,AB\n\r";
// 文字列を改行で区切って配列に格納する
var person:Array = csv.split("\n").join("").split("\r");
for(var i:Number=0; i < person.length;i++){
	// カンマで区切って配列に格納する
	var tempArray:Array = person[i].split(",");
	// 文字列を変換した配列に入れ替える
	person[i] = tempArray;
}

trace(person[0]); // 1,taro,A
trace(person[0][1]); // taro
trace(person[1][2]); // AB
```

***
この記事は、以前ブログで公開していた記事、内容を再編集したものです。
ActionScript 1.0/2.0/3.0とFlex 3の内容が中心です。
TextViewキーボード入力の改行を無効にする（キーボードを閉じる）

# 今日の結論
- TextViewDelegateのshouldChangeTextInRange()の中で、改行文字（"\n"）が入力された場合、キーボードを閉じる


↓こんな感じ↓

```swift
    func textView(textView: UITextView, shouldChangeTextInRange range: NSRange,
                        replacementText text: String) -> Bool {
        if text == "\n" {
            textView.resignFirstResponder() //キーボードを閉じる
            return false
        }
        return true
    }
```


# 経緯
iOSアプリ開発で、改行させたくないTextViewを配置する作業を行いました。
そこまで躓きはしなかったのですが、備忘録として・・・


# これもやっておこう
## キーボードのreturn（改行）ボタン
デフォルトのキーボードを使用すると
![キャプチャ.png](https://qiita-image-store.s3.amazonaws.com/0/61953/44790be0-5599-451a-60fd-8c1e0740193f.png)

右下のボタンが「return（改行）」と表記されるため、
改行を無効とする動作を行うときの表記としてはふさわしくない。

## キーボードを「Done（完了）」ボタンに変更
「return」の表記を変更するには、ソースコード内で下記の処理を行う

    textView.returnKeyType = .Done

![キャプチャDone.png](https://qiita-image-store.s3.amazonaws.com/0/61953/bb52c839-7a2b-2154-5454-c349e931411f.png)
「Done（完了）」に書き換わりました！！！

※ Interface Builder上でも変更できそうですね。
[TextView] -> [Return Key]

## その他
return、Done以外にも下記の変更が可能なようです。

```swift
enum UIReturnKeyType : Int {
    
    case Default
    case Go
    case Google
    case Join
    case Next
    case Route
    case Search
    case Send
    case Yahoo
    case Done
    case EmergencyCall

}
```
Defaultに該当するのが、returnのようですね。キーボードの目的にあったTypeを選択しましょう！
FuelPHPのValidationに直接独自ルールを追加する（PHP>=5.4）

Validationの拡張方法はあるけど既存ルールと同じようにFuel\Core\Validation内の内部メソッドを使って書いたりできないので不便。
traitを使って直接拡張することで$thisが使えるので便利になる。

#ソース 

* Fuel\Core\Validationを継承して新規クラスを作成

```php:fuel/app/classes/validation.php
<?php

class Validation extends Fuel\Core\Validation
{
	use Validation_Required;
}
```

* 新規ルールを作成

```php:fuel/app/classes/validation/required.php
<?php

trait Validation_Required {

	/**
	 * いずれかひとつ必須
	 */
	public function _validation_required_in_array( $val , $fields = array() ) {
		
```

* Bootstrapに新規クラスを追加

```php:fuel/app/bootstrap.php
Autoloader::add_classes(array(
	// Add classes you want to override here
	// Example: 'View' => APPPATH.'classes/view.php',
	'Validation' => APPPATH.'classes/validation.php',
));
```
ApplescriptでPDFに保管

VitalSourseのBookShelfからPDFにする方法です。
面倒臭かったのでスクリプト化してみました。備忘録がてら投稿してみます。
はじめての投稿はまさかのApplescriptとは。

そもそもVitalSourseBookshelfなるものが
印刷したいのに10枚ずつしか出力できないのを
少しでも楽しようと思って、開始ページを入力すれば10ページ先まで印刷するScriptを応用しました。
ただ、決まりきったキーを押していくだけなんですが、
かなり楽になりました。

きっと印刷部分を繰り返しにして10ページごとに繰り返してくれるのが理想なんだけど。

```lang:PDFsave
--開始のページを取得
set Start_val to text returned of ¬
	(display dialog ¬
		"最初のページを入力してください" with title ¬
		"印刷ページの先頭指定" default answer ¬
		"1" buttons {"OK", "Cancel"} ¬
		default button 1 cancel button 2)

--一度に出力できる枚数
set Incriment_Val to 10

tell application "VitalSource Bookshelf"
	activate
	delay 1

	--プリントのショートカットキー
	tell application "System Events" to keystroke "p" using command down
	delay 1

	--開始ページの指定
	tell application "System Events" to keystroke Start_val as string
	tell application "System Events" to keystroke tab

	--終了ページの指定
	tell application "System Events" to keystroke Start_val + Incriment_Val - 1 as string
	tell application "System Events" to keystroke tab
	tell application "System Events" to keystroke return
	tell application "System Events" to keystroke return
	delay 3
end tell

activate application "VitalSource Bookshelf"
tell application "System Events"
	tell process "Bookshelf"
		click menu button "PDF" of window "プリント"
		click menu button "PDF" of window "プリント"
		delay 1

		--キー下を２回押下してPDFで保管...を選択
		tell application "System Events" to keystroke (ASCII character 31)
		tell application "System Events" to keystroke (ASCII character 31)
		tell application "System Events" to keystroke return
		
		delay 2

		--ここは文字の選択を解除するため
		tell application "System Events" to keystroke (ASCII character 31)
		tell application "System Events" to keystroke (ASCII character 31)

		--ファイル名の入力
		tell application "System Events" to keystroke Start_val as string
		tell application "System Events" to keystroke "-" as string
		tell application "System Events" to keystroke Start_val + Incriment_Val - 1 as string
		delay 1
		tell application "System Events" to keystroke return
		
	end tell
end tell
```
FlashVars

FlashVarsを利用してFlashに値を渡す方法です。
ここでは`myURL=http://weblogs.adobe.com`をFlashに渡します。


```html:flashvars.html
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.adobe.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="550" height="400" id="myflashvars" align="middle">
<param name="allowScriptAccess" value="sameDomain" />
<param name="movie" value="myflashvars.swf" />
<param name="FlashVars" value="myURL=http://weblogs.adobe.com/">
<param name="quality" value="high" />
<param name="bgcolor" value="#ffffff" />
<embed src="myflashvars.swf" FlashVars="myURL=http://weblogs.adobe.com/" quality="high" bgcolor="#ffffff" width="550" height="400" name="myflashvars" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer_jp" />
</object>

<script type="text/javascript">
	//<!--
	var so = new SWFObject("myflashvars.swf", "myflashvars", "550", "400", "10", "#ffffff");
	so.addParam("FlashVars", "myURL=http://weblogs.adobe.com");
	so.write("myflashvars");
	//-->
</script>
```

```as3:flashvars.as
// ActionScript2.0の場合
trace(_level0.myURL);

// ActionScript3.0の場合
var flashVars:Object = this.loaderInfo.parameters;
trace(flashVars['myURL']);
```

***
この記事は、以前ブログで公開していた記事、内容を再編集したものです。
ActionScript 1.0/2.0/3.0とFlex 3の内容が中心です。
RSSリーダ

MXMLとASでつくるRSSリーダでRSSを取得してDataGridに表示します。

```mxml:rss.mxml
<?xml version="1.0" encoding="utf-8"?> 
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="init();"> 
<mx:Script> 
	<![CDATA[ 
	import flash.events.*; 
	import flash.utils.*; 
	import mx.events.*; 
	public var myXMLList:XMLList; 
	public function init():void{ 
		var url:String="http://dailynews.yahoo.co.jp/fc/rss.xml"; 
		var urlReq:URLRequest = new URLRequest(url); 
		var urlLoader:URLLoader = new URLLoader(urlReq); 
		urlLoader.addEventListener(Event.COMPLETE,completeHandler); 
	} 
	public function completeHandler(e:Event):void{ 
		myXMLList = new XMLList(e.target.data); 
		myDG.dataProvider=myXMLList.channel.item; 
	} 
	]]> 
</mx:Script> 
<mx:DataGrid id="myDG" width="100%" height="100%" horizontalCenter="5" verticalCenter="5"> 
<mx:columns> 
<mx:DataGridColumn headerText="title" dataField="title"/> 
<mx:DataGridColumn headerText="description" dataField="description"/> 
<mx:DataGridColumn headerText="pubDate" dataField="pubDate"/> 
</mx:columns> 
</mx:DataGrid> 

</mx:WindowedApplication>
```

***
この記事は、以前ブログで公開していた記事、内容を再編集したものです。
ActionScript 1.0/2.0/3.0とFlex 3の内容が中心です。
FileMakerのWebビューアでGoogleMapAPI連携。

## FileMakerをWebでリッチに！

FileMaker Pro Advanced買ったはいいが一向に使わなくて悲しいので少し試していたWebビューア周りをまとめておきます。
**グーグルマップのAPIと連携するサンプルを作りました。**

## WebビューアでグーグルマップAPI連携(JavaScript)

内容は以下のような流れです。

1. 【表示】FileMakerのWebビューアにGoogleMapAPIv3を使って地図を表示する。

2. 【操作】Webビューア内の地図をクリックしてマーカーを打つ。

3. 【保存】Webビューア内の保存ボタンでFileMakerにマーカーの緯度経度を保存する。

4. 【復元】FileMakerの地図情報に保存したマーカー位置を表示する。

![スクリーンショット 2014-12-25 23.06.26.png](https://qiita-image-store.s3.amazonaws.com/0/9907/6728c9f9-f2ba-30f0-9534-61e94e19a967.png)

## HTML
HTMLは1ファイルにHTMLとJavaScriptを書きます。

設定テーブルにHTML用のフィールドを用意しました。
![スクリーンショット 2014-12-25 23.10.47.png](https://qiita-image-store.s3.amazonaws.com/0/9907/53f80a14-7574-abbd-1249-a28665ec5ecb.png)


![スクリーンショット 2014-12-25 23.18.22.png](https://qiita-image-store.s3.amazonaws.com/0/9907/0b3d370c-d49b-aff3-170c-8c816f06d055.png)
配置したWebビューアに「viewer1」という名前をつけ、スクリプトから実行してやります。
URLはデータURIスキームで指定し、設定テーブルのhtmlを格納してある変数$htmlを付け足します。

## 【保存】Webビューア内(JavaScript)から FileMakerへデータを渡す。

Webビューア内でクリックしてマーカーを打ち、保存ボタンを押したタイミングで地点データを保存します。
保存するときは以下のような感じでJavaScriptからFileMakerのスクリプトを呼び出します。

<pre>
function save() {
    window.location = 'fmp://$/webViewerTest.fmp12?script=receive&$data1=100&$data2=200'
}
</pre>
「webViewerTest.fmp12」がファイル名、「script」がスクリプト名。
「\$data1」、「\$data2」はスクリプト内でローカル変数として使えます。
\$を付けるのがポイントのようです。

今回作ったものだと以下の赤枠の中がWebビューアから受け取ったデータになります。
![スクリーンショット 2014-12-26 00.06.29.png](https://qiita-image-store.s3.amazonaws.com/0/9907/694f0d43-2743-e14f-b84b-98aada2001bf.png)

見ての通り\$lng1,\$lng2などのように変数に連番を振っていますが、どうやって取り出すのでしょう。
可変変数というやつです。
Evaluateという関数を使うようです。
Loopは\$numberというのをJavaScript側から受けっとっているのでそれを上限とします。

\$countをカウントアップします。
<pre>
Evaluate (

"Let ( 
[v = $lng" & $count &"];
v
)"

)
</pre>

## 【復元】FileMakerからWebビューア内にデータを渡す。

保存した地点データを復元します。

複数ある可能性がある地点データをSQLで「:::」区切りで取得します。
Substituteでhtml内にあらかじめ書いておいた文字列と置換します。

今回FileMakerで初めてSQL使いました。
![スクリーンショット 2014-12-25 23.30.29.png](https://qiita-image-store.s3.amazonaws.com/0/9907/d6596293-7be9-4235-9ad2-57e0daa3948d.png)

SQL実行して返ってきた値。
![スクリーンショット 2014-12-25 23.35.45.png](https://qiita-image-store.s3.amazonaws.com/0/9907/5a9ebb28-eea4-426f-fb5c-97640f5fead2.png)

地図データの緯度、経度、ズーム、地点データ(:::区切りのカンマ区切り)はJavaScriptで1地点毎に分割しさらにID、緯度、経度に分割します。

## 結論
データの受け渡しの窮屈さある。
標準でJsonとか容易に扱えるようになったらいいのにな。
SQLは簡単なSELECT文だけ使ってみたが普通に使えた。
Webビューア使うとやっぱ印象よくなる。

## ソース
ファイルはこちらにおいておきます。
MacOSX10.10でFileMaker13 Pro Advancedでしか実行してません。

https://github.com/niiyz/FileMaker-GoogleMapAPIv3
RDFの解析

RDFの解析方法です。名前空間がある場合は、Namespaceを宣言しないとうまく解析できません。

```as3:rdf.as

private var myXML:XML; 
//Namespace 
private var rss:Namespace = new Namespace("http://purl.org/rss/1.0/"); 
private var rdf:Namespace = new Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#"); 
private var dc:Namespace = new Namespace("http://purl.org/dc/elements/1.1/"); 
private var content:Namespace = new Namespace("http://purl.org/rss/1.0/modules/content/"); 

private function init():void{ 
	var urlLoader:URLLoader = new URLLoader(); 
	var urlReq:URLRequest = new URLRequest("./sample.rdf"); 
	urlLoader.load(urlReq); 
	urlLoader.addEventListener(Event.COMPLETE,completeHandler); 
	urlLoader.addEventListener(IOErrorEvent.IO_ERROR,errorHandler); 
} 

private function completeHandler(e:Event):void{ 
	default xml namespace = rss; 
	myXML = new XML(e.target.data); 
	var items:XMLList = myXML.item; 
	var parseArr:Array = new Array(); 
	for(var i:uint = 0;i < items.length();i++){ 
		parseArr.push({title:items[i].title, 
		content:items[i].content::encoded}); 
		trace(parseArr[i].title); 
		trace(parseArr[i].content); 
	} 
} 

private function errorHandler(e:ErrorEvent):void{ 
	trace(e); 
} 

```

```as3:sample.xml
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
xmlns="http://purl.org/rss/1.0/" 
xmlns:dc="http://purl.org/dc/elements/1.1/" 
xmlns:content="http://purl.org/rss/1.0/modules/content/" 
xmlns:cc="http://web.resource.org/cc/" 
xml:lang="ja"> 
	<channel rdf:about="http://www.xml.com/cs/xml/query/q/19"> 
		<title>Test RSS</title> 
		<link>http://www.adobe.com/</link> 
		<description>This is a test RSS document.</description> 
		<language>en-us</language> 
		<items> 
		<rdf:Seq> 
			<rdf:li rdf:resource="http://www.adobe.com/devnet/flash/"/> 
			<rdf:li rdf:resource="http://www.adobe.com/devnet/flex/"/> 
		</rdf:Seq> 
		</items> 
	</channel> 
	<item rdf:about="http://www.adobe.com/devnet/flash/"> 
		<title>Adobe Flash Developer Center</title> 
		<link>http://www.adobe.com/devnet/flash/</link> 
		<description>Welcome to the Flash Developer Center</description> 
		<dc:creator>Adobe</dc:creator> 
		<dc:date>2005-08-08</dc:date> 
	</item> 
	<item rdf:about="http://www.adobe.com/devnet/flex/"> 
		<title>Flex Developer Center</title> 
		<link>http://www.adobe.com/devnet/flex/</link> 
		<description>Welcome to the Flex Developer Center</description> 
		<dc:creator>Adobe</dc:creator> 
		<dc:date>2005-10-16</dc:date> 
	</item> 
</rdf:RDF>
```


***
この記事は、以前ブログで公開していた記事、内容を再編集したものです。
ActionScript 1.0/2.0/3.0とFlex 3の内容が中心です。
アドベントカレンダーへの投稿方法とQiita公式アカウントへのリンク

Qiitaを使い始めたばかりで、Qiitaの機能とか使い方を検索することが多かった。
最初にここ見ればよかったのね、と後から知ったことのメモ。

#Advent Calendarについて
**アドベントカレンダーとはなんぞや、という人へ**
http://qiita.com/kyproject/items/915ba4df14f7ab411961

**アドベントカレンダーのトップページ**
http://qiita.com/advent-calendar
フッター部分に「Advent Calendar一覧」という名前でリンクされていたけど、初めてQiita使った私は気づかなかった。

上のページにアクセスできれば、あとは直感的にリンクをたどることでこの機能の意味がわかってくる。
募集中テーマに参加登録するのも迷うことなく出来る。
迷ったのが投稿方法。

#どうやってアドベントカレンダーに投稿するの？
~~**"参加登録テーマ名"と"AdventCalendar”のタグをつけて投稿するみたいです。**~~
~~間違っていたら教えてください！~~

###**早速下記のコメントで、正しい投稿方法を教えていただきました!!**
コメントをご覧ください！（2014/12/26追記)



「アドベントカレンダー 投稿方法」で検索すれば[公式アカウントの記事](http://qiita.com/Qiita/items/dd327e5d9eb513320555)がでてくる。
しかし、タイトルは”8/1よりiOSアドベントカレンダーを開始します!”で、ピンとこなかったし、記事が12年7月と古い。


>Qiitaトップページより"iOS", "AdventCalendar”の2つのタグをつけて投稿してください．他のタグを付けてもOKです．
>(追加はスタッフが手動で行うため，アドベントカレンダーページへの反映は多少タイムラグが生じます)

こんな感じの説明のため、iOSに限らずテーマがたくさんある今、どうすべきかという明確な言及がない。
個人的にQiitaはとても面白く、英語に苦手意識のある日本人プログラマにとって欠かせないサービスになるんじゃないかと思う。
だからこそ。もっと使い勝手が良くなってほしい、という期待をこめてメモ。
検索ボックスにワードを打ち込む時間と、これで本当に合ってるのか？と迷って他のリンクもたどってしまう時間がもったいないものね。

#Qiitaの公式アカウント
http://qiita.com/Qiita

トップページ上で、公式アカウントへのリンクが見つからない。
初めてQiitaを使う人は、公式アカウントが存在するかどうかもわからない。
最初に見ておいてもよかったかなーと思ったのでメモ。
cpコマンドを使ったスクリプトを作るときに引っかかりそうなこと

覚え書きのようなもの。単純なことだけど、忘れないように。
違う！とか、こうすればいいじゃん！みたいなのはガンガンご指摘ください。
追加があったら随時更新するかも。

# 存在しないディレクトリ下にコピーはできない  
何を当たり前のことを、と書いていて思いましたｗ  
でもこんなケース。
例えばカレントディレクトリにあるhugaという空のディレクトリの下に、hogehogeというディレクトリを作ってその下にhuga.txtをコピーしようとする、例えば
  
```bash
cp -rf /hoge/huga.txt /huga/hogehoge/huga.txt
```  

みたいなことをするとエラーになっちゃいます。
rオプション（aオプションも）でやってくれるのは、**ディレクトリを**再帰的にコピーするところで、何となく存在しないディレクトリがあるときはこのオプションが何とかしてくれるだろう、と思っていると失敗します（体験談）  
わかりづらいですが、期待としては「コマンド実行時には存在しないhogehogeディレクトリを作成した上で、huga.txtをその中にコピーしてくれること」なのですが、そううまくは行かないということらしいです。
うまいことやる方法はないもんですかねえ。

# ディレクトリごとコピー時に、コピー先を同名ディレクトリにすると、コピー先の有無によって結果が変わる
これもアレっと思ったポイントでした。  
例えばカレントディレクトリにあるhogeというディレクトリをコピーするときにhuga/hogeとコピー先指定した場合（hugaディレクトリは既に作成済みとする）

```bash
cp -r hoge huga/hoge
```

huga/hogeというディレクトリが既に存在するか否かで結果が変わります。  

* huga/hogeが既に存在する場合
huga/hogeの下にコピー元のhogeディレクトリがコピーされる。
つまり、**huga/hoge/hoge**となる。

* huga/hogeがまだ存在しない場合
hugaの下にコピー元のhogeディレクトリがコピーされる。
つまり、**huga/hoge**となる。

ファイルリストを読み込んで、それをコピーする簡単なスクリプトを作ったんですが、ファイルリストに書いてあるものがディレクトリだった場合、ここで引っかかります。  
これを回避するために、コピー元がディレクトリか否かをチェックし、ディレクトリの場合はrsyncでコピーするようにしました。


そもそもrsyncでいいじゃん！という気はするんですけどね…。
FuelPHP valid_stringのエラー時に、使用可能文字を日本語化したい


```php:fuel/app/classes/validation/error.php
<?php

class Validation_Error extends Fuel\Core\Validation_Error
{
	/**
	 * Override
	 *
	 * @param   error message to parse
	 * @return  string
	 */
	protected function _replace_tags($msg)
	{
		$msg = parent::_replace_tags($msg);
		
		$find = __('validation.valid_string_params');
		if( $find ){
			foreach( $find as $param => $str ){
				$msg  = str_replace($param,$str,$msg);
			}
		}
		
		return $msg;
	}

}
```

```php:fuel/app/lang/ja/validation.php
<?php

/**
 * バリデーション時エラーメッセージ定義
 */

return array(
	/**
	 * for Overridden Validation_Error
	 */
	'valid_string_params' => array(
		'alpha'        => 'アルファベット',
		'utf8'         => '全角文字', 
		'numeric'      => '数値',
		'spaces'       => 'スペース', 
		'newlines'     => '改行', 
		'tabs'         => 'タブ', 
		'punctuation'  => 'punctuation', 
		'singlequotes' => 'シングルクオート', 
		'doublequotes' => 'ダブルクオート', 
		'dashes'       => 'ハイフン', 
		'brackets'     => 'brackets', 
		'braces'       => 'braces',
	),
```
【余談】なぜbaserJSをつくったのか


Webサイトと詳しいAPIリファレンスはこちら [baserJS Webサイト](http://baserproject.github.io/baserjs/)

## コーポレートサイトにちょうどいいJavaScriptライブラリ

baserCMSの謳い文句のひとつが「コーポレートサイトにちょうどいいCMS」です。

このフレーズ、好きなんですよ。なので、ふとある日「コーポレートサイトにちょうどいいJavaScriptライブラリ」っていうのもアリだなぁと思ってTwitterとかで呟いたのが作ろうと思ったきっかけです。

## なぜ「baser」なのか

もうひとつ作ろうと思った動機になったのが、NPO法人[ベーサー・ファウンデーション](http://baserfoundation.org/)ができたことです。

このNPO法人を作るにあたって、活動内容を「baserCMSに限らない」としたことで、baserCMS 以外のオープンソースプロジェクトもやっていこうという方針になったのです。

>ベーサー・ファウンデーションでは、「日本製」、「シンプル」というキーワードを持って、特に技術的なノウハウを「土台」として提供する事でこの問題を解決したいと考えています。

>そこで、すでにオープンソース化している「baserCMS」というCMSパッケージを中心に、「オープンソース」という世の中のノウハウを集約できるインフラを利用する事で、制作者においては情報収集及びWebサイト構築の簡易化・簡素化、運営者においては構築コスト・運営コストの圧縮を行い、Webサイト業界に貢献していきます。

そこで baserJS を提案して baserCMS と並行して活動を行っていけたらいいなと思ったのです。

Web開発者を助ける側面もあるbaserCMSの設計方針において、バックエンドはサポートするけれどフロントエンドをサポートしないのはおかしいな、という考えもありました。

## 自信がないからオープンソース化したかった

baserJS は前身のライブラリがあります。社内だけで使いまわしていたjQueryプラグインです。社内でメンテナンスできる人間は少なく、しかし要望はどんどん増えて、中途半端な設計もあり変に肥大化し、しかもCoffeeScriptで書いていたものだからソースはスパゲッティになっていきました。

誰かに助けてもらいたかったし、せめてコードレビューのひとつでも、と思っていました。これ以上、バグや要望をひとりで抱えるのは厳しい。仲間が欲しかったんです。

と言ってもまだソースコードを触っているのは僕ひとりなので、これから少しずつ開発者を募れたらいいなぁと思っています。オープンソース化することでだいぶそのあたりの気が楽になっている部分があります。

## 5年遅いJavaScriptライブラリ

NPO法人の活動に乗っかっちゃったわけなので無責任に開発するわけにはいきません。ある程度の機能をもたせたbaserJSですが、これかどうするかも考えていかないといけません。

### いつまでjQueryに依存するのか

正直、昨今のフロントエンド事情を考えるとどう考えても時代遅れです。5年前に公開していれば、もしかしたらちやほやされたかもしれません。

色々とそこは悩むところで「コーポレートサイト」を謳っている以上、今は未だIE8を切り捨てるなんてできませんし、そこを前提にするとjQueryは必須です。MV*やWebComponentなどの近未来のWeb技術も気持ち的にはどんどん導入していきたいですが、Webアプリケーションを作るわけではないし、あくまで所謂「ホームページ」なので必要性も悩むところです。

### 取り込める技術は取り込めたい

なぜTypeScriptを使って開発しているかというと、メンテナンス性や堅牢性もありますが、たぶんそういった気持が強いです。

今後も [Browserify](http://browserify.org/) 基準でモジュールを管理することにしようと考えていたり、お問い合わせフォームにおけるEFOに特化した機能を付加させたり、WAI-ARIAに対応してDOM操作をしたり、マーケティングだったりアクセシビリティだったり多方面の最新を取り込みたいと思っています。

## コーポレートサイト枠で尖れるか

SPAやWebアプリケーション界隈では、立派なライブラリを天才たちがガンガン作っていますが、単純なウェブサイトでいうと先の活発さに比べればだいぶ成熟してきていると思います。

最近はフォーカスされるのが技術やアーティスティックな部分ではなく、UXやIAになってきているので、それの基板となるサイトの汎用的な部分に関してはbaserJSでサクサクと叶えられるようになるのが理想です。

「とりあえずjQuery」みたいな感じで「とりあえずbaserJS」にしたいんです。もちろん最先端から蔑まれるを覚悟の上で、です。

* * *

以上、余談でした。

機会があれば baserJS どうぞよろしくお願いいたします。
Bloggerでトップページのみにガジェットや広告を表示する方法

Bloggerでガジェットや広告をTOPページのみ表示したい時に使えます。

- data:blog.url : 現在のページのURL
- data:blog.homepageUrl : BloggerのTOPページ
 
b:if condで使用してください。

```
<!-- only display top page -->
<b:if cond='data:blog.url == data:blog.homepageUrl'>
HTML
</b:if>
```
■公式ページ
グローバルに利用可能なデータ部分が参考になります。
https://support.google.com/blogger/answer/47270?hl=ja

■実際にガジェットをページにより表示/非表示を変更しています。
[ぽぽぽぽーんのNWとOSS](http://komeiy.blogspot.jp)
simplecovによるカバレッジの計測


##動機
現職の会社はウォーターフォールを推奨する会社です。当然仕様変更があります。今回テストを作成しつつ開発した結果、客観的に判断してくれる第三者ができました。この客観的第三者の信頼度をカバレッジとして出せたら良いじゃないかという話です。ちなみにテストケースを作ってたのはRORの案件ではないです。

##前提
 + Rails開発環境は整い済み
 + RSpecは導入済み。

##手順
 + インストール！

```
$ gem install simplecov
```
 + 後は普通にRspecの感じでテスト作ってを実行する
 + なんかターミナルにカバレッジ出る！
 + と思ったらcoverageディレクトリができている。
 + index.htmlを開く。
 + カバレッジ出てる！このHTMLはRailsを意識しておる！

##結論
 + 画像がないと感動に対する派手さに欠ける。
 + 動機を書いてる時が最高潮になっちゃった。
 + 前に書いたRspecのやつ、実行までしてない。
Ansibleでrun_onceを付け忘れた話

研究室のUbuntu Serverでaptを更新するのに，Ansibleを使っています．
そこで「今から更新するよ!」をTypetalkに通知しようとして失敗した話です．

## Typetalkモジュール

AnsibleにはTypetalkに通知するためのモジュールがあります．

  - [typetalk - Send a message to typetalk &mdash; Ansible Documentation](http://docs.ansible.com/typetalk_module.html)

このモジュールは，こんな感じで使えます．

```yaml
- typetalk:
    client_id=abcdefghijklmnopqrstuvwxyz123456
    client_secret=abcdefghijklmnopqrstuvwxyz123456789abcdefghijklmnopqrstuvwxyz123
    topic=1234
    msg='サーバーアップデートを開始します!'
```

ただ，そのまま使ってしまうと，大変なことになります．
「対象ホストの数だけ通知を送ってしまう」のです．
(研究室のチャットに20件の通知を出してしまいました…．)

## run_onceオプション

> このため、1.7から導入されたrun_onceを使います。run_onceは、グループ内の先頭で定義されたホストでのみ実行されるようにするためのパラメーターです。
> 『[Ansibleでの連番ホスト名をつけるなど &mdash; そこはかとなく書くよん。](http://tdoc.info/blog/2014/10/04/ansible_hostname.html)』

先程のPlaybookにrun_onceを付けると，1度だけ通知されるようになります．

```yaml
- typetalk:
    client_id=abcdefghijklmnopqrstuvwxyz123456
    client_secret=abcdefghijklmnopqrstuvwxyz123456789abcdefghijklmnopqrstuvwxyz123
    topic=1234
    msg='サーバーアップデートを開始します!'
  run_once: true
```

### まとめ

Ansibleから通知をする場合，`run_once`を付け忘れないように，という教訓でした．
実際に使っているPlaybookは，GitHubに上げています．
TypetalkのTokenは`hosts`に書くなどの工夫をしています．

  - [ansible-playbooks/apt.yml at master · hico-horiuchi/ansible-playbooks](https://github.com/hico-horiuchi/ansible-playbooks/blob/master/apt/apt.yml)
MongoDBのバックアップ方法の比較

MogoDBのバックアップ方法について調査していたら、MongoDB社のスタッフのブログに簡潔にまとまっているものがあったので、翻訳して紹介します。英語が得意な人は原文を読んで下さい(※急いで書いたので誤訳があるかもしれません)。

MongoDB Backup Strategies Compared
http://blog.mms.mongodb.com/post/86915115595/mongodb-backup-strategies-compared

----

MongoDBのバックアップの方法は主に3つあります。

* mongodump：MongoDB付属のユーティリティを使用する方法。
* データファイルのコピー：LinuxのLVMやAWSのEBSなどを使用してファイルシステムのスナップショットを取得する方法。
* MongoDBの管理サービス(MMS)：MMSのバックアップ機能を利用する方法。

それぞれについての詳細は、以下の通りです。

#### mongodump

mongodumpは、MongoDBのデータをバックアップするMongoDB付属のツールです。 mongodumpは、データベース全体、コレクション、クエリの結果をダンプすることができます。oplogをダンプすることで、一貫性のあるデータのスナップショットを生成することができます。バックアップ後は、mongorestoreを使用することで、新規または既存のデータベースにデータを復元できます。mongorestoreは、mongodumpによって生成されたBSONデータベースダンプから、コンテンツをインポートし、oplogを再生します。

mongodumpは、直接的なアプローチであり、特定のニーズに基づいてフィルタリングされたバックアップを生成できる利点があります。小規模なシステムにおいては十分なソリューションですが、大規模なシステムには適していません。多くの負荷を及ぼすため、スケーラブルなソリューションとは言い難いです。また、差分アプローチではないので、スナップショットの各時点で完全なダンプを必要とし、リソースを大量に消費します。使用しているシステムが大規模になるにつれて、ファイルシステムのスナップショットやMMSのような影響の低いソリューションを検討する必要があります。

さらに、mongodumpを小規模なシステムで実行する場合はあまり問題にはなりませんが、大規模なシャード化されたシステムで実行する場合は複雑さが伴います。

#### データファイルのコピー

データベースプロセスがデータを保存するために使用するファイルをコピーすることで、MongoDBをバックアップすることができます。データベースの一貫性のあるスナップショットを取得するには、データベースに対するすべての書き込みを停止して、標準のファイルシステムのコピーツールを使用するか、ファイルシステム全体のスナップショットを生成する必要があります(ボリュームマネージャがそれをサポートしている場合)。

例えば、Linux LVMは、バックアップとリストアの目的でコピーされたファイルのスナップショットを、迅速かつ効率的に生成します。ただし、スナップショットの論理的な一貫性を保証するには、MongoDBのジャーナリング機能を有効にする必要があります。

フルバックアップを取ってそれらを復元することに関しては、バックアップがストレージレベルで取得されるため、ファイルシステムのスナップショットの方がmongodumpよりも効率的な手法となりえます。しかし、mongodumpとは異なり、バックアップに特定のデータベースやコレクションをターゲットにする柔軟性が無いという点で、より粗いアプローチと言えます。この方法の場合、巨大なバックアップファイルが生成され、バックアップ操作の時間が長くなる可能性があります。

システムが大規模、複雑化するにつれて、ファイルシステムのスナップショットの実行は、継続的なメンテナンスを必要とします。複数のレプリカセット間でのバックアップを調整するためには(特にシャード化されたシステムでは)、さまざまなコンポーネント間の整合性を確保するためのdevopsの専門知識を必要とします。

#### MongoDB管理サービス (MMS)

MMSは、完全に管理されたサービスとしてMongoDBの継続的なオンラインバックアップを提供します。MongoDBを使用している環境にバックアップエージェントをインストールすると、セキュアで冗長化されたMongoDBのデータセンターに対して初期同期を行います。その後、継続的なバックアップをするために、MMSは暗号化して圧縮されたoplogを送信します。

デフォルトでは、MMSは6時間毎にスナップショットを取り、oplogを24時間保持します。スナップショットのスケジュールやリテンションポリシーは、要件を満たすように設定することができます。また、非ミッションクリティカルなデータベースやコレクションを除外するための柔軟性も持っています。

レプリカセットに対しては、カスタム・ポイントインタイムのスナップショットにより、過去24時間内の任意の瞬間に復元することができます。 シャード化されたシステムにおいて、MMSは一貫性のあるクラスタのスナップショットを6時間毎に生成します。また、シャード化されたクラスタのきめ細かいリストアのために、チェックポイントを使用するオプションがあります。

MMSは、oplogだけを読み取るため、継続的なパフォーマンスへの影響は最小限に抑えられます。

クラウドベースのサービスに加えて、MMSはMongoDBのStandardまたはEnterpriseサブスクリプションの一部としてオンプレミスソフトウェアとして利用可能です。
Goのflagパッケージで同名の引数を複数受け取る

Goのflagパッケージで以下のようなことをやりたい。

```bash
test-cli --data value1 --data value2 --data value3
```

[flag - The Go Programming](http://golang.org/pkg/flag/)

同じ名前の引数が複数登場する。

flagパッケージにはValueという型が用意されていて、これを満たす独自の型を用意してVar()に渡してあげる。

以下の例はでは、引数dataで指定された値をstringのスライスで受け取る実装です。[]stringを拡張した独自のstrslice型を用意して、flag.Valueを満たすためStirng()とSet()を実装しています。

```go
package main

import (
	"flag"
	"fmt"
)

type strslice []string

func (s *strslice) String() string {
	return fmt.Sprintf("%v", multiflag)
}

func (s *strslice) Set(v string) error {
	*s = append(*s, v)
	return nil
}

var multiflag strslice

func main() {

	flag.Var(&multiflag, "data", "Data values.") 
	flag.Parse()

	fmt.Printf("%v", multiflag)
}

```

実行結果

```bash
$ ./test-cli --data value1 --data value2 --data value3
[value1 value2 value3]
```
NSOperationQueueを使って、安心・安全にマルチスレッド処理を行う

この記事は[iOS Advent Calendar 2014](http://qiita.com/advent-calendar/2014/ios)の25日目の記事です。
※今回の記事を読む前に[昨日のAndroidの記事](http://qiita.com/kaneshinth/items/12919e8f46d1eb670cc8)を読むことをお勧めします。

12月もとうとう25日ですね！
本日はみなさん共通の知り合いの誕生日ですね。お祝いですね。

そんな共通の知人へのお祝いを二人でどうぞしてください。
※共通の知人：キリスト

----

では、本題に入りましょう。今回はスレッド周りの話をします。

【何故、クリスマスにスレッドの話】

そりゃもう、マルチスレッドを巧みに扱う人はこんな大切な日でもマルチスレッド並みにN股くらい仕掛けているんだろうなぁ。という話ですよ。

さらにはスレッドセーフなので、同時刻に複数人と会っても彼氏・彼女達に感づられることも無いのでしょうね。素晴らしい。


さて、そんなシングルスレッド。いや、ゼロスレッドの画面の前のみなさんも、マルチスレッドの扱いに長けることさえできれば来年は明るいクリスマス（イブ）が待っていますよ。（スレッドセーフでお願いします）


さてさて、話を戻しましょう。
スレッドは理解している人からすると、簡単に扱えるし効率的に使用することができます。
しかし、初心者の方（特にクリスマスに予定がない方）からすると「スレッド 扱い わからない [検索]」はあるあるだと思うのでそういった方向けです。

ちなみに、このくだりは昨日の[Android Advent Calendar 2014](http://qiita.com/advent-calendar/2014/android)の記事で使っています。

----

## UIのカクツキ、Ａ・Ｎ・Ｒ！

皆さんはアプリを作っていているとUIのカクツキにいつかはぶち当たるでしょう。

そして突然の……

```
＿人人人人人人人人＿
＞  クラッシュ！  ＜
￣ＹＹＹＹＹＹＹＹ￣
```



## `NSOperation`クラス


「自前で実装している処理が重い！」

そんなときのケアは自分で行わないといけません。

重い処理を`NSOperation`を継承した別クラスにあるオーバーライドした`main`メソッドに定義します。

そのクラスのインスタンスを生成し、別スレッドに渡して処理をメインスレッドと分けることによってめっちゃ重たい処理をメインスレッドから切り離します。

```swift
import Foundation

class Operaion: NSOperation {

    override init() {
        super.init()
        self.queuePriority = NSOperationQueuePriority.Normal
    }

    override func main() {
        for i in 1...100 {
            NSLog("%@, Loop: %d", NSThread.currentThread(), i)
        }
    }

}
```

今回は`Operation`というクラスを実装しました。それを違うスレッドで処理するにはGCDで別スレッドを取得します。簡単ですね。

```swift
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
    Operaion().start()
})
```

これだけで別スレッドでの処理が実現できます。

ただし、UIに関する処理は **必ず** UIスレッド（メインスレッド）で行ってください。

※必ずしも、`NSOperation`クラスを別で実装する必要はありません。UIViewController上で定義しても良いですし、クロージャーで定義してもよいです。


## `NSOperationQueue`クラス

大体の非同期な処理は先ほどの実装で済むかと思います。

ですが、タスクを何回かの複数のスレッド上で行いたい場合、しっかりとスレッドを管理してあげないと意図しない挙動となったり、ANRが発生することもあります。

では、そのスレッドを管理するマネージャークラスを自前しますか……Noですね。今の時代はなんでも揃っています。


Foundationフレームワークには`NSOperationQueue`というものが存在します。

これを使って簡単に効率的でスレッドセーフなマルチスレッド処理を実装することができます。

```swift
var queue = NSOperationQueue()
```


### 使い方

必要なところで`NSOperationQueue`の`addOperation`メソッドに`NSOperation`で定義されたサブクラスを突っ込みます。

```swift
var queue = NSOperationQueue()

for i in 1...10 {
    queue.addOperation(Operaion())
}
```

これで、`maxConcurrentOperationCount`に設定されているスレッド数で処理が並行に走ります。

## おわりに

この記事は昨日書いたAndroidのマルチスレッドの話をiOSに変えてみました。

そのため、Android <--> iOSで相互にスレッドの話を理解したい人、どうぞ一例として参考にしてみてください。

----

今回、改めてiOSとAndroidのスレッドを比較しましたが、`NSOperationQueue`はかなり使いやすいですね。

今回のサンプルプロジェクトのリポジトリはこちらです。

https://github.com/kaneshin/Thread-Test-iOS

今回はスレッドに関してで、UIスレッドには触れていません。

ですが、UIスレッドとの連携も考える必要はあります。また、今度時間があればいろいろと紹介します。


昨日の[Android Advent Calendar 2014](http://qiita.com/advent-calendar/2014/android)の記事もよろしくお願いします。

※無理やり、Androidの話を変えた部分もあるので、省略等多いですが多めに見てあげてください
RubyInstaller for Windowsでのgem installでSSL_connectエラーになる場合

結論としては、以下の記事と一緒。
[Gem - RubyでHTTPS接続時にSSL証明書のエラーがでる。 - Qiita](http://qiita.com/iorionda/items/1babb333e130c8dc70c6 "Gem - RubyでHTTPS接続時にSSL証明書のエラーがでる。 - Qiita")

でも、Windowsの場合はどこから新しい証明書ファイルをダウンロードすればよいかわからなかった。

なお、一次情報源はここ [Workaround RubyGems' SSL errors on Ruby for Windows (RubyInstaller)](https://gist.github.com/luislavena/f064211759ee0f806c88 "Workaround RubyGems' SSL errors on Ruby for Windows (RubyInstaller)")

## 環境
- Windows7 64bit
- RubyInstaller for Windows 2.0.0-p481   ←古いのが原因

## 状況
次のようなエラーメッセージが表示されました。

```bash
$ gem i berkshelf
ERROR:  Could not find a valid gem 'berkshelf' (>= 0), here is why:
        Unable to download data from https://rubygems.org/ - SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (https://rubygems.org/latest_specs.4.8.gz)
```

## 原因
SSL証明書の有効期限切れ

## 解決方法① ～有効な鍵を追加する～
RubyInstallerの最新版7zipアーカイブに含まれる、SSL証明書ファイルをコピーする

```bash
$ 7zip ruby-2.1.5-x64-mingw32.7z
$ cp ruby-2.1.5-x64-mingw32\lib\ruby\2.1.0\rubygems\ssl_certs\* ruby-2.0.0-x64-mingw32\lib\ruby\2.0.0\rubygems\ssl_certs
```

もしくは、特定の証明書だけダウンロードして保存する

```bash
cd ruby-2.0.0-x64-mingw32\lib\ruby\2.0.0\rubygems\ssl_certs
curl -O https://raw.githubusercontent.com/rubygems/rubygems/master/lib/rubygems/ssl_certs/AddTrustExternalCARoot-2048.pem
```

## 解決方法② ～rubygemsをupgradeする～
ruygemsを自動でアップグレードするgem(ruby-gems-update.gem)をインストールしなければならなかったりとめんどくさい。

```bash
# rubygems-update-1.8.30.gemをダウンロードしておく。
$ gem install --local C:\rubygems-update-1.8.30.gem
$ update_rubygems --no-ri --no-rdoc
$ gem uninstall rubygems-update -x
```

## 解決方法③ ～新しいRubyを入れる～
RubyInstaller for Windowsの最新版をダウンロードしてインストールする。
博士課程Advent Calendar 2014

これは、博士課程Advent Calendar 2014の記事です。匿名希望です。

私は、現在は完全に回復しているが、完全大血管転位症という先天性心臓病を持って生まれ、当時は実験的だった根治手術を受けて完全回復した生き残りである。私と同時期に同じ病院で同じ手術を受けた、私を含む22名の子供のうち、6名が死亡した。自分が博士課程を志望した理由の半分は、博論の謝辞に、自分と同じ心臓病を持って生まれ、実験的な手術に挑戦して失敗した子らの挑戦を記録するためである。

私が手術をした当時、完全回復できるが実験的な根治手術の他に、20代～30代まで延命でき手術成績も確かな延命手術（姑息手術）があった（この疾患は手術なしでは数歳のうちに100%死亡するので、完全回復できる根治手術を受けるのは、ほぼ10代以前の子供に限られる）。しかし、私を含む22名は、姑息手術を選ばず、失敗するリスクを承知のうえで、当時実験的だった根治手術に挑戦した。
その上で亡くなった子らは、サイエンスの進歩のために自らを犠牲にして挑戦した、とみなせると思うが、彼らの挑戦はサイエンスの世界からほぼ完全に忘れ去られている。もちろん、亡くなった子らは、ご親族や病院から何らかの形で供養されていると思うが、それらは、必ずしも彼らの挑戦を記録するものではない。

彼らの挑戦の存在については、半永久的に残る性格を持つ文書の中で記録する必要があると私は思った。単純に、彼らの挑戦について誰かが評価してやらねば、彼らがせっかくリスクを背負ってまで根治手術を受けた事が報われないのではないか、と、そう思ったのだ。しかし、そのような記録を半永久的に保存してくれる文書というのは、世の中には博論の謝辞以外、世の中に殆ど無い。こういうことは、記念碑を立てる性格のものではないし、既に何年も前の事なので、触れられたくない方も多いだろう。だから、あくまで個人の考えである事が明確でありながら、同時に、公文書でもあるという不思議な性格を持つ、博論の謝辞の中で、「こういう事が記録に値すると思った人がいた」という事を、小さく書いておくぐらいが良いと思う。今更、大きく取り扱っても、誰も得をしない。

もちろん、「博士課程を志望した理由の半分」と書いたように、これだけの為に博論を書いたわけではない。亡くなった子らの挑戦を記録するだけで自分の人生を終わらせてしまっては、逆に、彼らに申し訳が立たない。だから、自分のキャリアにプラスになる選択肢を取りたかった。また、研究職は自分の名前が記録される仕事でもある。完全回復した者の責務として、世に名前が残る性質の仕事がしたかった、という理由も大きい。

私は、アラサーの現在まで特に何事も無く健常者とほぼ同等に生きており、博士号が取れている。この疾患を持つ子は、約2000分の1の確率でランダムに生まれてくる。願わくは、私と同じ疾患を持った次の世代の子らの人生が、幸福でありますように。
ruby2.2.0をインストール


#インストール
anyenvからrbenvを再インストール（update用のプラグインを利用すべきだったかも）

`rbenv install -l`
で2.2.0があるのを確認

`rbenv install 2.2.0`
しばらく待つ


さてさてrubyのバージョンを
`rbenv global 2.2.0`
これで2.2.0になったぞ！

`rbenv rehash`
意味があるのか知らないけれど、ひとまず唱えてみた。

#問題発生
gemはちゃんとなっているかな〜
`gem list`

・・・あれ？ちょっとしかない・・・

これまで`rbenv rehash`をサボっていたせいでしょうorz

仕方がないので、バージョンを戻してからgem一覧を見てGemfileを生成。

```up.rb

gems = `gem list`.split("\n")
gems.map!{|gem|gem.scan(/^(.+)\s\(/)}
gems.flatten!
File.open("Gemfile","w") do |f|
  f.puts 'source \'https://rubygems.org\''
  f.puts gems.map{|gem| "gem \"#{gem}\""}
end

```

再度バージョンを2.2.0にしてbundle install !!
しようにもbundlerがまだ入っていないので
`gem install bundler`

で今度こそ`bundle install`。
一応`gem update`。

これで十分だろう。さて新メソッドを試してみよう！
オブジェクト指向とは呪である

※ この投稿は[オブジェクト指向 Advent Calendar 2014 - Qiita](http://qiita.com/advent-calendar/2014/oop) の12/25の記事です。

## 安倍晴明 オブジェクト指向について語ること##

「おい晴明、おれはまたわからなくなってしまったよ。オブジェクトとは一体何なのだ」

「オブジェクト指向のオブジェクトのことか」

「そうだ、そのオブジェクトだ。まあ、クラスの書き方はこうだ、それをインスタンス化するにはどうだということはなんとなくわかるのだが、そうやって書くことがどんな意味を持っているのか、おれにはさっぱり……」

「そうか、わからぬか。ならば答えよう。オブジェクトとはな、呪（しゅ）だ」

「ちょっと待て晴明、それはいくらなんでも乱暴だろう!? 」

「何が乱暴だ。時代設定を無視してオブジェクトとは何だなどと問うてきたのは博雅よ、お前のほうではないか」

「いやそれはそうなんだが……しかし、お前のいつもの『名とは呪だ』といい、何でもかんでも呪にしてしまうというのはどうなのだ」

「別に何でもかんでも呪にしているわけではない。おれは、これは呪だと思うものしか呪とは言わぬさ。そもそも、プログラミングにおいては適切な名づけこそが読みやすくバグの少ないコードにつながる。名が呪であるならば、オブジェクト指向に限らず、プログラミングという行為そのものが呪であるとすら言えるだろう」

「ううむ、そういわれるとそんな気もするような、うまく丸め込まれたような―――」

「ははは、まだ納得がゆかぬか。ではこういうのはどうだ。お前はいつぞや、朱雀門に現れた鬼と笛を合奏したと言っていたな」

「うむ、あれは不思議な夜であった。どこからともなく美しい調べが流れてきて、思わず自分の笛を合わせてしまったのだ。あの時はまさか、相手が人ならぬ存在であるとは夢にも思わなんだが―――」

「さて、そこよ。お前は人であり楽士である。だからこのように書ける」

```csharp

public class Human
{
（略）
}
public class MusicPlayer : Human
{
  public void Play(Instrument instrument)
  {
   （略）
  }
}
public class Program
  public static void Main(string[] args)
  {
    MusicPlayer Hiromasa = new MusicPlayer()
    Hiromasa.Play(new Flute());
  }
}
```

「なるほど、人を継承した楽士クラスを定義して、おれという楽士のインスタンスを生成するのだな」

「そうだ。他にも源脩どのや敦実親王など、楽を奏するものはみな楽士クラスのインスタンスとして生成できる。これで宮中の宴での合奏ができるな」

「うむ」

「ところが、そこへ鬼がふらりと現れて『おれも合奏に加えてくれ』と言ったとしよう。鬼は人と一緒に楽を奏することはできるだろうか？ 」

「ううむ……いや、無理だろうな」

「そうだな、人はみなおびえて逃げ出すか、あわてて鬼を追い払ってしまうだろう。鬼は人ではない。だから人を継承した楽士にはなれぬというわけだ。だが、中にはおまえのように、相手が鬼であるか人であるかにはとんと執着せず、よい楽を奏でていれば自分も合わせて奏したいと思うような物好きもいる」

「いや、別に執着しないわけではないぞ。ただ知らなかっただけだ」

「まあそれはどちらでもよい。ともあれ、お前が鬼と笛を合わせたいと思うならば、楽士が人を継承したままであってはうまくいかぬ」

「ではどうするのだ」

「楽士は人を継承するのをやめてしまうのさ。そして、人と鬼とを『楽を奏するもの』という呪でくくる。これが、オブジェクト指向型の言語でよく用いられる、インタフェースだ」

```csharp
public class HumanPlayer : IMusicPlayer
{
  public void Play(Instrument instrument)
  {
    （略）
  }
}
public class GoblinPlayer : IMusicPlayer
{
  public void Play(Instrument instrument)
  {
    （略）
  }
}
public interface IMusicPlayer
{
  public void Play(Instrument instrument);
}
public class Program
{
  public static void Main(string[] args)
  {
    IMusicPlayer Hiromasa = new HumanPlayer();
    IMusicPlayer Oni = new GoblinPlayer();
    List<IMusicPlayer> Players = new List<IMusicPlayer>  { Hiromasa, Oni };
    foreach(var player in Players)
    {
       player.Play(new Fluet());
    }
  }
}
```


「なるほど、人の楽士も鬼の楽士も、楽を奏するという同じメソッドを持っているから奏でる楽を合わせられるということか」

「そうだ。しかもおまえはさきほど自分で言ったように、相手が鬼であるか人であるか知らなくてよい。ただ楽を奏するこころを持っている、すなわち楽士インタフェースを実装していることさえ知っていれば、同じように合奏することができるのだ」

「ふむ、それは良いな」

「これはインタフェースだけではない。メソッドも、クラスも、オブジェクト指向における、名を持つものたちはみな同じ働きを持っているのさ」

「すべてか」

「うむ、すべてだ。ある時は目的に見合ったインスタンスを返すものにFactoryと名をつけ、またある時はある条件にかなっているかを調べることの頭にIsとつける。このように、曖昧模糊とした事物に名前をつけ、呪でくくることによってものごとがうまくまわるようにとりはからうことができる。これこそがオブジェクト指向プログラミングの目指すところであり、おれがオブジェクトとは呪であると述べる所以なのさ」



## 元ネタ ##
![陰陽師](http://ecx.images-amazon.com/images/I/513EE3SA8WL.jpg "陰陽師") [Amazon.co.jp： 陰陽師(おんみょうじ) (文春文庫): 夢枕 獏: 本](http://www.amazon.co.jp/dp/4167528010)
## おまけ ##
私の勝手な解釈のつもりで書いておりましたが……

>Schemeでは値に名前を付けることを束縛(bind)と呼んでいます。

[プログラミングとは名前付け(bind)である - karetta.jp](http://karetta.jp/book-node/gauche-hacks/008225)

おおう。bind＝くくる、と考えると意外に的を射たかも。
高速な辞書実装に使えるトライ木をD言語とPythonで書いてみた

##トライ木とは
トライ(Trie)木というデータ構造をご存知でしょうか？
トライ木は高速な辞書の実装に使えるデータ構造です。LOUDSというデータ構造を使って実装すると，非常に少ないメモリで木を表現できるという利点があります。トライ木は例えばかな漢字変換(Google日本語入力など)において，国語辞典をメモリに保持するために用いられています。

トライ木はこんなカタチをしています。
![trie tree](http://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Trie_example.svg/250px-Trie_example.svg.png)
(図は[Wikipedia](https://en.wikipedia.org/wiki/Trie)より引用)

他の木と違うところは、木の"枝"にあたる部分にラベルが付いていることです。

これを辞書として使うにはどうすればいいでしょうか。
"in"を検索してみましょう。簡単です。i -> n とたどればいいだけです。「5」が検索結果として取り出せますね。
"inn"を検索してみましょう。今いる「5」の位置から下に動けばいいだけです。「9」が結果として取り出せます。

##トライ木の特徴
###高速に検索できる
このトライ木、何がすごいかというと、検索がすごく高速にできるんです。トライ木では検索速度は検索するキーの大きさに比例します。そして、__木の大きさには比例しません！__

例えば、トライ木で国語辞典を実装したとします。
その国語辞典で12文字の「わらうかどにはふくきたる」を検索するには、3文字の「わらう」を検索する場合のだいたい4(=12/3)倍の時間がかかります。
しかし、辞書に100単語入っていようが100万単語入っていようが、同じ単語を調べる場合、理論上検索速度は変わりません。すごいですね。

###ムダな検索を減らせる
また、共通する部分がある文字列を検索する場合、検索を途中から再開させることでムダな検索を減らすことができます。
例えば先ほど"inn"を検索したときは、"in"を検索した結果の「5」のノードから検索を再開することで、素早く"inn"の検索結果を見つけることができました。

##LOUDSによる実装
トライ木を構造体やポインタを使って何も考えずに実装するとものすごくメモリを食います。メモリ確保が忙しすぎてヘタするとマシンがフリーズします。
そこでLOUDSというデータの表現方法を使います。
LOUDSを使うとノード1つをたった2ビット程度で表現できます。
最初に示した図のようなノードが11個ある木でもたった23ビットで表現でき、なんとlong型の変数1つに収まってしまいます。

ここでLOUDSの説明といきたいところですが、[簡潔データ構造 LOUDS の解説](http://d.hatena.ne.jp/takeda25/20120421/1335019644)が非常にわかりやすかったのでそちらに譲ります。

##コード
コードは以下です。D言語とPythonそれぞれで実装しました。
[github.com/IshitaTakeshi/Louds-Trie](https://github.com/IshitaTakeshi/Louds-Trie)
コメントはたくさん書いたつもりなので、上記リンクのLOUDSの解説を読んでからコードを読めば理解できると思います。
疑問点やおかしいと思った点があればコメントするかtwitterで言っていただければ対応します。

## パッケージ版
D言語のパッケージ管理システムDUBで扱えるようにしました。
[DUBのページ](http://code.dlang.org/packages/dtrie)
[ソースコード](https://github.com/IshitaTakeshi/DTrie)