OmniAICreator/Qiita-1.07M huggingface dataset:
【C#】あるとちょっと便利な拡張メソッド紹介

# gloops advent calenda 19日目

[gloops advent calendar](http://qiita.com/advent-calendar/2016/gloops) 19日目です:santa_tone2:

はじめまして。 gloopsの s_mino_ri です。
社内ではゲームの運用に携わっているとともに、常にC#の情報を追いかけている生粋のC#オタクでもあります。

# あるとちょっと便利な拡張メソッド

ここでは、私が運用に携わっているゲームで使用している、独自定義された拡張メソッドを紹介していきたいと思います。
**※読みやすさを優先して、引数のnullチェックや例外処理は基本的に省いています**
※以下で紹介するメソッドは、すべて現場で使われているままの名前です

## そもそも拡張メソッドとは？

[拡張メソッド (C# プログラミング ガイド)](https://msdn.microsoft.com/ja-jp/library/bb383977.aspx)
拡張メソッドとは、C#に用意された言語機能のひとつで、あたかも「既存の型(クラスなど)にメソッドを追加したように見える」メソッドです。
実態はクラスの外にあるただのstaticなメソッドので、クラス内のprivateな変数などにはアクセスできません。
有名なところでは[LINQ](https://msdn.microsoft.com/ja-jp/library/bb397926.aspx)が主に拡張メソッドで実装されていますね。

当然、拡張メソッドを使いすぎるとメソッドがどこで定義されているのか分からなくなるなどデメリットもあるため、乱用は禁物です。

## ページ分け表示処理

```csharp:Pagenate
public static IEnumerable<T> Paginate<T>(this IEnumerable<T> source, int pageSize, int currentPage)
{
    return source.Skip(pageSize * (currentPage - 1)).Take(pageSize);
}
```

大量にあるデータを5件ずつなどで区切ってページ分け表示する際に使用します。
単純ですが、ページ分けする場所それぞれにSkipとTakeを書くよりも一貫性が出て読みやすくなります。

## 確率算出

```csharp:CalcProbability
public static double CalcProbability<T>(this IEnumerable<T> source, Func<T, int> rateSelector, Func<T, bool> predicate)
{
    var denominator = source.Sum(rateSelector);
    var numerator = source.Where(predicate).Sum(rateSelector);
    return numerator / (double)denominator;
}
```

ソーシャルゲームにガチャはつきもの。
このメソッドは、ある集団の中で、特定の集団が選択される確率を計算します。
rateSelectorは要素(ガチャの排出アイテムなど)から、その要素に割り当てられた排出の重み値を選択する述語です。

## 小分けに分割

```csharp:Chunk
public static IEnumerable<IList<T>> Chunk<T>(this IEnumerable<T> source, int chunkSize)
{
    var result = new List<T>(chunkSize);

    foreach (var item in source)
    {
        result.Add(item);
        if (result.Count < chunkSize) continue;
        yield return result;
        result = new List<T>(chunkSize);
    }

    if (result.Any())
        yield return result;
}
```

RxにあるBufferとほぼ同じ動作をする拡張メソッドです。大量のデータを、ある個数ごとに分割して返します。
たとえば、所持アイテムを5個ごとに折り返して表示する場合などに使用します。

## LINQの流れで文字列にする

```csharp:StringJoin
public static string StringJoin<T>(this IEnumerable<T> source, string separator)
{
    return string.Join(separator, source);
}
```

LINQでシーケンスを加工した後、そのままstring.Joinしたい時に頭から囲うのは面倒……。
という要件を叶えるだけのメソッドです。

## Dictionaryに絶妙に足りないメソッド

```csharp:GetValueOrDefault
public static TValue GetValueOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
{
    TValue result;
    dictionary.TryGetValue(key, out result); // keyが見つからない場合は result に default(TValue) が代入される
    return result;
}
```

標準ライブラリのDictionaryは、「特定のキーが見つからない場合に規定値を返す」という要件を満たすメソッドがありません。
TryGetをこのために使うと、毎回変数を先に宣言しないといけないため少し不便…ということで用意したメソッドです。

## SQLのBETWEEN...AND...を移植

```csharp:InBetween
public static bool InBetween<T>(this T value, T min, T max)
    where T : IComparable<T>
{
    return value.CompareTo(min) >= 0 && value.CompareTo(max) <= 0;
}
```

ある値が、下限～上限の間に入っているか判定する拡張メソッドです。
不等号の単純なミスを無くしてくれる上、コード上の値の並び順が分かりやすくなります。

# まとめ

拡張メソッドは、うまく使うとコードの可読性を上げ、一連の処理を再利用しやすくします。
しかし、前述したようにデメリットもあり、「パッと見で誰が定義したメソッドか分かりにくくなる」「ワンライナー化が(過剰に)進み、コードが横に伸びやすくなる」などのかえって可読性を低下させるような効果をもたらすこともあります。

便利な機能ですが、使いすぎには気を付けましょう。
F# ScriptでPythonの__name__を真似する

最初に起動したスクリプトなのか、別のスクリプトから読み込まれたスクリプトなのか、実行時に判定する方法を調べました。

【2020.05.28】 F# Interactive に対応しました。

コマンドライン引数については以下の記事を参照してください。

* [F#スクリプトで引数の扱いをすり合わせる](https://qiita.com/7shi/items/9c3340d04ec0450678c4)

F# スクリプトを手軽に扱うには VS Code + Ionide がお勧めです。

* [F#開発環境の紹介](https://qiita.com/7shi/items/5fc7d6477d96bbd7a71d)

# Python

Pythonでは以下のように記述することで、最初に起動されたのかimportされたのかを判断することができます。

```py3:test1.py
if __name__ == '__main__':
    print("main")
```
```py3:test2.py
import test1
```
```text:実行結果
$ python test1.py
main

$ python test2.py
```

# F# スクリプト

これをF# スクリプトで真似してみました。一時変数が残らないように `do` 内に記述します。

```fsharp:Test1.fsx
do
    let frames = System.Diagnostics.StackTrace().GetFrames()
                 |> Array.map (fun frame -> frame.GetMethod().Name)
    if frames.[0] <> "main@" || Array.contains "EvalParsedSourceFiles" frames then () else
    printfn "main"
```
```fsharp:Test2.fsx
#load "Test1.fsx"
```
```text:実行結果
>fsi Test1.fsx
main

>fsi Test2.fsx

>fsc Test1.fsx
Microsoft (R) F# Compiler バージョン 10.6.0.0 for F# 4.7
Copyright (C) Microsoft Corporation. All rights reserved.

>fsc Test2.fsx
Microsoft (R) F# Compiler バージョン 10.6.0.0 for F# 4.7
Copyright (C) Microsoft Corporation. All rights reserved.

Test2.fsx(1,18): warning FS0988: プログラムのメイン モジュールが空です。実行しても何も処理されません

>Test1
main

>Test2
```

## 調査

このコードはスタックフレームの差分に基づいています。

```fsharp:Test3.fsx
for frame in System.Diagnostics.StackTrace().GetFrames() do
    printfn "%s" (frame.GetMethod().Name)
```
```fsharp:Test4.fsx
#load "Test3.fsx"
```
```text:ログ採取
>fsi Test3.fsx > Test3.log
>fsi Test4.fsx > Test4.log
```
```diff:差分
--- Test3.log   2020-05-28 05:37:40.295828000 +0900
+++ Test4.log   2020-05-28 05:37:46.470496400 +0900
@@ -9,8 +9,8 @@
 iter
 Iterate
 ProcessInputs
-EvalParsedDefinitions
-EvalParsedExpression
+EvalParsedSourceFiles
+EvalSourceFiles
 Invoke
 InteractiveCatch
 ExecInteraction
```

`EvalParsedDefinitions` があれば最初の起動、`EvalParsedSourceFiles` があれば別のスクリプトから読み込まれていると判断できるようです。

# 旧バージョン

当初は次のようにしていました。Python の記述方法に似ていますが、F# Interactive に未対応です。

```fsharp:Test1.fsx
if System.Diagnostics.StackTrace().GetFrame(0).GetMethod().Name = "main@" then
    printfn "main"
```
```fsharp:Test2.fsx
#load "Test1.fsx"
```
```text:実行結果
>fsi Test1.fsx
main

>fsi Test2.fsx
main

>fsc Test1.fsx
Microsoft (R) F# Compiler version 11.0.50727.1
Copyright (c) Microsoft Corporation. All Rights Reserved.

>fsc Test2.fsx
Microsoft (R) F# Compiler version 11.0.50727.1
Copyright (c) Microsoft Corporation. All Rights Reserved.

Test2.fsx(1,18): warning FS0988: Main module of program is empty: nothing will happen when it is run

>Test1
main

>Test2
```

# 参考

* [.NET で呼び出し元のメソッド情報を知りたいときは - 周回遅れのブルース](http://d.hatena.ne.jp/hilapon/20130216/1360986092) 2013.02.16
Metalの恩恵は受けつつCore Imageで「手軽に」画像処理

Metalでシェーダを書けば自由自在にGPU-acceleratedな画像処理を行えるわけですが、[Core Imageの200種類近くある豊富なフィルタ](http://d.hatena.ne.jp/shu223/20150622/1434924215)を利用しつつ、**Metalの恩恵も受ける**、という選択肢もあります。

既存のCore Imageのフィルタ（`CIFilter`）を利用することで、以下のようなメリットがあります。

- 自分でイチから書かなくて良い
  - もちろんこっちの方が楽
  - 画像処理のプロが書いたであろうものを利用した方が大抵の場合良い結果が得られる
- [種類がたくさん](http://d.hatena.ne.jp/shu223/20150622/1434924215)ある
- 簡単に使える
  - **数行書くだけ**
  - **どのフィルタも基本的な使い方は同じ**
- CIFilterは**Metalとシームレスに統合**されるようにつくられている（後述）
- ビルトインフィルタの一部はMetal Performance Shadersを用いて実装されている


![coreimage.gif](https://qiita-image-store.s3.amazonaws.com/0/3180/f5da7f90-a2ff-5bd6-a784-9b8004bfee9f.gif)

（Core Imageの`CIPixellate`フィルタをパラメータを変えつつ**60fps**でMTKViewに描画。実装方法は後述）



###MetalとCIFilterの連携について

「Metalとシームレスに統合」と上で書きましたが、それだけ言われてもなんのこっちゃ、という感じだと思います。

このテーマについてはWWDC2015の「[What's New in Core Image](https://developer.apple.com/videos/play/wwdc2015/510/)」というセッションで詳しく解説されています。

![insert_.png](https://qiita-image-store.s3.amazonaws.com/0/3180/06916dcd-2817-86e5-3e0c-5a78f76e8f02.png)

上の図は、**Core Imageのフィルタはコマンドバッファのどこにでも挿入**できるよ、ということを言っています。

「MetalでリサイズしたテクスチャをCore Imageで画像処理してMetalで描画」みたいなことをしたいとして、そのために**CPUとGPUを行ったり来たり**みたいなムダなことはしないので安心して併用してください、ということかと思います。


##実装

**`MTLTexture`にCore Imageで画像処理 → `MTKView`に描画**する、という実装例を示します。

MetalでGPUベースレンダリングするためのコンテキスト（`CIContext`）を生成しておきます。

```swift
private let device: MTLDevice
private let context: CIContext
```

```swift
device = MTLCreateSystemDefaultDevice()!
context = CIContext(mtlDevice: device)
```

`MTLTexture`から入力用の`CIImage`を生成します。

```swift
let inputImage = CIImage(mtlTexture: texture, options: nil)
```

何らかのCore Imageフィルタ（`CIFilter`）を生成し、入力画像とパラメータをセットします。

```swift
let filter = CIFilter(name: "CIPixellate")!
filter.setValue(inputImage, forKey: kCIInputImageKey)
filter.setValue(50.0, forKey: kCIInputScaleKey)
```

`MTKView`の`drawInView:`メソッド内で、CIFilterの出力画像（`outputImage`）を描画します。

```swift
guard let outputImage = filter.outputImage else {return}
let commandBuffer = commandQueue.makeCommandBuffer()

let colorSpace = CGColorSpaceCreateDeviceRGB()
context.render(outputImage, to: drawable.texture, commandBuffer: commandBuffer, bounds: outputImage.extent, colorSpace: colorSpace)
    
commandBuffer.present(drawable)
commandBuffer.commit()
commandBuffer.waitUntilCompleted()
```

`CIImage`を`CAMetalDrawable`の`texture`（`MTLTexture`）に書き込むために、`CIContext`の`render(_:to:commandBuffer:bounds:colorSpace:)`を使用するのがポイントです。[^1]

[^1]: MTKViewを用いて2Dテクスチャを表示する基本についてはこちらに書いてあります：[MetalでUIImageViewライクに画像を表示する - 最小実装編 - Qiita](http://qiita.com/shu223/items/3301a1e64757c0bd73ef)

###注意点

`MTLTesture`から`CIImage`を生成する際、**画像が上下反転**してしまいます。

というわけで実際にはy方向にフリップさせて使ってます。

```swift
let inputImage = CIImage(mtlTexture: texture, options: nil)?.applying(CGAffineTransform(scaleX: 1, y: -1).translatedBy(x: 0, y: CGFloat(texture.height)))
```
[メモ] pythonで1行timezoneクラス作成

ちょっとしたpythonコードを書く際に、日時扱う事はよくあると思います。
そんな時、timezoneが必要になりいちいちpytzをpipインストールするのは面倒だなと感じたため、timezoneクラス(tzinfo継承クラス)を1行で作ってみました。

# メモコード

## １行コード
``` １行コード.
JST = type('JST', (__import__('datetime').tzinfo,), {'_tzname': 'JST', '_zone': 'Tokyo', '_utcoffset': __import__('datetime').timedelta(hours=9), '__module__': 'timezone', '__str__': lambda self: self._zone, '__repr__': lambda self: '<tzinfo {} {} {}>'.format(self._zone, self._utcoffset, self._tzname), 'utcoffset': lambda self, dt: self._utcoffset, 'dst': lambda self, dt: __import__('datetime').timedelta(0), 'tzname': lambda self, dt: self._tzname})
```

## pep8準拠コード
``` pep8準拠コード.
JST = type(
    'JST',
    (__import__('datetime').tzinfo,),
    {'_tzname': 'JST',
     '_zone': 'Tokyo',
     '_utcoffset': __import__('datetime').timedelta(hours=9),
     '__module__': 'timezone',
     '__str__': lambda self: self._zone,
     '__repr__': lambda self: '<tzinfo {} {} {}>'.format(
         self._zone, self._utcoffset, self._tzname),
     'utcoffset': lambda self, dt: self._utcoffset,
     'dst': lambda self, dt: __import__('datetime').timedelta(0),
     'tzname': lambda self, dt: self._tzname}
)

```

## JST日時をUTC系の時間に変換
``` datetimeにjstタイムゾーンを付加してutcのstruct_timeを作ったりepoch_timeを取得したり.
>>> JST = type('JST', (__import__('datetime').tzinfo,), {'_tzname': 'JST', '_zone': 'Tokyo', '_utcoffset': __import__('datetime').timedelta(hours=9), '__module__': 'timezone', '__str__': lambda self: self._zone, '__repr__': lambda self: '<tzinfo {} {} {}>'.format(self._zone, self._utcoffset, self._tzname), 'utcoffset': lambda self, dt: self._utcoffset, 'dst': lambda self, dt: __import__('datetime').timedelta(0), 'tzname': lambda self, dt: self._tzname})
>>>
>>> import datetime
>>> import calendar
>>>
>>> # JSTのtzinfo継承クラス生成
>>> jst = JST()
>>> jst
<tzinfo Tokyo 9:00:00 JST>
>>>
>>> # replaceでtzinfoを付加
>>> jst_datetime = datetime.datetime.now().replace(tzinfo=JST())
>>> jst_datetime
datetime.datetime(2016, 12, 16, 18, 54, 6, 749383, tzinfo=<tzinfo Tokyo 9:00:00 JST>)
>>>
>>> # jstのdatetimeからutcのstruct_timeを取得
>>> jst_datetime.utctimetuple()
time.struct_time(tm_year=2016, tm_mon=12, tm_mday=16, tm_hour=9, tm_min=54, tm_sec=6, tm_wday=4, tm_yday=351, tm_isdst=0)
>>>
>>> # jstのdatetimeからepoch timeを取得
>>> calendar.timegm(jst_datetime.utctimetuple())
1481882046
```

# あとがき
今回は、日本のタイムゾーン JSTを作成しましたが、「_utcoffset」「_zone」「_tzname」あと「dstメソッド」を修正する事でサマータイムのある別のタイムゾーンを作る事も出来ます。

皆さんも、是非timezoneでちょっとしたコードを書きたい時は使ってみて下さい。
WiX Toolset Qiita記事のまとめ

# うわっ･･･WiX Toolsetのググラビリティ、低すぎ･･･？
はい。低すぎます。
「WiX」でググった日には「なんでホームページ作らなきゃいけないんだ！！」ってなります。
なので、Qiita内にある記事だけでもまとめておけば多少は役に立つかな？

## Qiita記事のまとめ
以下にQiita記事にあるWiX Toolsetが絡んでいる記事をまとめておきます。
実際にWiX Toolsetの解説しているもののみならず、本文中にあればまとめています。
見つけた順に追加していますので、情報としてはバラバラしてます・・・ごめんなさい

### WiX Toolsetを解説している記事
* [WiX ToolsetでWelcomeDlgとExitDlgを出さないようにする](http://qiita.com/tohshima/items/cb07f5d0caed7caa5fb3)
* [WixにおけるFeatureの扱い方の注意](http://qiita.com/skitoy4321/items/f946f643854ba13a4d96)
* [WiX toolset x86とx64の判断](http://qiita.com/MugMog/items/7f54f27cfaca2f1d5156)
* [WiX Toolsetで使えるUI画面](https://qiita.com/tohshima/items/19f3b220ebc36801edbe)
* [Windows Installer手引書 Part.1 はじめに] (https://qiita.com/tohshima/items/dc4c4721d50a2ad70c7a) (Part.33+1までの目次あり)
* [WiXを使って無料でインストーラーを作る！] (https://qiita.com/Yanase-Takuma/items/bf0a360c9d37ca03a272)
* [続・WiXを使って無料でインストーラーを作る！] (https://qiita.com/Yanase-Takuma/items/4529ee6520a47d3b6479)
* [Wix Toolset でインストーラーのUIを使う方法] (https://qiita.com/masoo/items/5191e1ffabd24cb69631)
* [【WiXToolset】アンインストールしたら常駐タスクを落とす](https://qiita.com/belre/items/0d4a74451f2f7533c0fe)
* [Burn のことってあまりかかれていないよね？](https://qiita.com/Tocchann/items/923a8a27ee1378298941)
* [WiX Toolset の昔話なんかを残しておこうかと…](https://qiita.com/Tocchann/items/049c81f881c64d320392)
* [WPF(.NET Core 3.0)をWixでMSIにする方法の一例](https://qiita.com/kwhrkzk/items/6eaf72a6c24379645deb)
* [[WiX] msi の upgrade 時の話](https://qiita.com/ktbkrjj/items/a210cb524c379feb71cf)
* [多言語化されたWindows Installerを作成する](https://qiita.com/hanashima/items/b2a2c4ac5b65ca6f4544)

### WixSharp でのインストーラー開発について書かれている記事
> Wix#（ウィックスシャープ）は、CS-Scriptファミリーの一員です。Wix#は、プレーンなC#シンタックスで書かれたスクリプトファイルを実行することにより、完全なMSIまたはWiXソースコードを構築することができます。
[oleg-shilo/wixsharp (GitHub)](https://github.com/oleg-shilo/wixsharp)

* [wixsharpでインストーラーを作る](https://qiita.com/skitoy4321/items/111ca55899473b9c2df4)
* [WiXSharpでサービスを登録する方法と、WiXSharpで日本語を含めたときにランタイムエラーになるのを防ぐ方法](https://qiita.com/nao-a/items/31fd03fe5f8867420766)

### WiX Toolsetが絡んでいる記事
* [Installerあれこれ](http://qiita.com/dharry/items/363485e80833773deead)
* [インストーラー作成ツールの選択](http://qiita.com/tohshima/items/314143d605f8ae1e0d87)
* [Visual Sdutio Code のインストーラ](http://qiita.com/dharry/items/f05afeb0b1c352afe3e4)
* [クリップボードの中身を整形するツールをあえてJavaで作ってみた](http://qiita.com/uzresk/items/5f6ec264ff4b3ccabe3a)
* [CMakeで大きめのプロジェクトを構成するためのメモ](http://qiita.com/shibukawa/items/af7ff2e1178fbb3ab6de)
* [Windows + Visual Studio で Static Link できる Qt をビルドする](http://qiita.com/informationsea/items/df2775c325769d6f56b3)
* [「JJUG CCC 2016 Spring」に行った](http://qiita.com/y_q1m/items/d350d59eda7003d31257)
* [インストーラ いくつか] (https://qiita.com/yuki_nishina/items/9ff9dfbbc9d2b0d70644)
* [【正規表現】テキストエディタの置き換え機能で正規表現を使って、テキスト修正作業で楽をしよう【XML-1】](https://qiita.com/belre/items/f2e29eec9a4506cf6dc9)

## WiX Toolsetの入門
WiX Toolsetによってインストーラーを開発しようとした場合、まずはこのHPを見て勉強しましょう。
[WiX チュートリアル 日本語訳](http://wix-tutorial-ja.github.io/)

英語が平気な人は本家サイト
[WiX Toolset Tutorial](https://www.firegiant.com/wix/tutorial/)

## 最後に
やっぱり記事少ない。
インストーラーを作ろうっていう人少ないんでしょうね。
この記事は不定期で更新していく予定ですが、新しい記事が見つからなければ更新されません。。。

---
*2022/02/07 更新*
前回更新からおよそ3年たってました。
その間に総記事数 50 over !! 手順書としてまとめられた方もいらっしゃるし大変いいことだと思います！
[JAWS-UG CLI] CloudWatch Logs:#10 サブスクリプションフィルタの削除

前提条件
========


CloudWatch Logsへの権限
--------------

CloudWatch Logsに対してフル権限があること。



AWS CLI
-------

以下のバージョンで動作確認済

- AWS CLI 1.11.28

```bash:コマンド:
aws --version
```

```text:結果(例):
      aws-cli/1.11.7 Python/2.7.11 Darwin/15.6.0 botocore/1.4.64
```

バージョンが古い場合は最新版に更新しましょう。

```bash:コマンド:
sudo -H pip install -U awscli
```


0. 準備
===========


AWS IDの取得
-----------------

```bash:変数の設定:
AWS_ID=$( \
        aws sts get-caller-identity \
          --query 'Account' \
          --output text \
) \
        && echo ${AWS_ID}
```

結果(例)

      XXXXXXXXXXXX




1. 事前作業
===========


1.1. ロググループの指定
-----------------------

```bash:変数の設定:
LOGS_GROUP_NAME='RDSOSMetrics'
```

1.2. ログフィルタの指定
-----------------------

```bash:変数の設定:
LOGS_FILTER_NAME='datadog'
```



2. サブスクリプションフィルタ削除
=================================

サブスクリプションフィルタを作成します。

```bash:変数の確認:
cat << ETX

        LOGS_GROUP_NAME:      ${LOGS_GROUP_NAME}
        LOGS_FILTER_NAME:     ${LOGS_FILTER_NAME}

ETX
```

```bash:コマンド:
aws logs delete-subscription-filter \
        --log-group-name ${LOGS_GROUP_NAME} \
        --filter-name ${LOGS_FILTER_NAME}
```

結果(例):

      (戻り値なし)


3. 事後作業
===========

```bash:コマンド:
aws logs describe-subscription-filters \
        --log-group-name ${LOGS_GROUP_NAME} \
        --filter-name-prefix ${LOGS_FILTER_NAME}
```

```json:結果(例):
{
    "subscriptionFilters": []
}
```

完了
====
DI (依存性の注入)っていったいなんだ？

**※以下の内容は社内研修での勉強内容を転載したものとなります。**

* * *

DIとか本を読んでもよく分からなかったので調べました。

# DI
DI = Dependency Injection

- 「依存性の注入」とよく訳される。（けどなんだかいまいちよく分からずスッキリしない、、、）
- dependencyを英訳すると*「A dependency is an object that can be used (a service).」*。つまりDIとは、「依存性の注入」じゃなくて、**「オブジェクトの注入」**ということらしい。（こっちの方がなんとなくわかるかも。）

## そもそも依存しているとはどのような状態？
- 「クラスAをコンパイルするためには（あるいは正しく動かすためには）、クラスBが既に出来上がってないとだめ」という状態のこと。
- こういう状態にあることを「クラスAはクラスBに依存している」という。

## 依存性が高いと困ること
- 単体テストがしづらい。
- 依存しているクラスBが壊れるとクラスAも使えないし、どちらに原因があるのか特定しづらい。
- そこで「依存性をクラスの外で定義すればいいんじゃないの？」という発想が生まれてくる。

## つまりDI=依存性(オブジェクト)の注入を行うとは？
- クラスAがクラスBに依存しているという情報を、クラスAの外で定義して外からクラスAのインスタンスに突っ込んであげるということ。
- 簡単に言うと「依存性（オブジェクト）を**外から**注入したい」ということ。
- これが実現されると、クラスBがなくてもクラスAを動かせるようになる。つまり粗結合になり、テストしやすくなる。

参考
・[要するに DI って何なのという話](http://nekogata.hatenablog.com/entry/2014/02/13/073043)
・[DI・DIコンテナ、ちゃんと理解出来てる・・？](http://qiita.com/ritukiii/items/de30b2d944109521298f)

# DIコンテナ
- 単純に言えば、DIを実現するためのフレームワーク(箱、入れ物)。
- DIを自動で行い、インスタンスを組み立ててくれる基盤。
- ただし、DIコンテナがないとDIが実現できないわけではない。

# DIを実現するための仕組み
以下のように定義をおこなっていくことでDIが実現される
## ApplicationContextとBean定義
- Spring FrameworkではApplicationContextがDIコンテナの役割を担う。

``` java:DIコンテナからインスタンスを取り出す実装例
ApplicationContext context = new AnnotationConfigurationContext(AppConfig.class); ①
UserService userService = context.getBean(Userservice.class); ②
```
①コンフィギュレーションクラスを渡してDIコンテナを生成。
②DIコンテナからUserServiceインスタンスを取得。

- ApplicationContextはBeanFactory(**※1**)の有する機能以外に以下の機能を有する。
 - URL やファイルのようなリソースへのアクセス
 - ApplicationListener インタフェースを実装したビーンへのイベントの伝播
 - 複数のコンテキストをロード可能

**(※1)**
・Spring の中でもっとも基本となる重要なパッケージは org.springframework.beans パッケージと org.springframework.context パッケージ。
・Dependency Injection の基本的な機能はこれらのパッケージが提供している。
・これらのパッケージのなかでも JavaBeans を管理する実際のコンテナとして中心的な役割を果たすのが BeanFactory。
・BeanFactory は依存関係が記述された定義ファイルを元に JavaBeans の生成・管理を行う。

- 実装例のAppConfigクラスは、DIコンテナに対する設定ファイル。
- 「Java Config」とも呼ばれる。
- Java Configクラスの実装例についてはp.16~17参照

ApplicationContextを使ったアプリケーションでは

- DiコンテナにConfigurationを使用して、コンポーネントを登録し、ApplicationContextインターフェースを通じてDIコンテナからBeanを取得する。
- DIコンテナに登録するコンポーネントを「Bean」、Configurationのことを「Bean定義」と呼ぶ。
- DIコンテナからBeanを取得することを「ルックアップ」と呼ぶ。 

参考
[2. BeanFactory と Bean 定義](http://www.techscore.com/tech/Java/Others/Spring/2/)

## 代表的なBean定義(Configuration)
① JavaベースConfiguration
→ @Configurationアノテーションが付与されたJavaクラスに@Beanアノテーションが付与されたメソッドを使用し、Beanを定義する方法。
② XMLベースConfiguration
→ XMLファイル中の<bean>要素のclass属性にFQCN(完全修飾クラス名)を記述し、<constructor-arg>や<property>要素を使ってインジェクションの設定を行う方法。
(内部構造が分かりやすいがエラーがわかりにくい)
③ アノテーションベースConfiguration
→ @Componentなどのまあーカーアノテーションが付与されたクラスを「コンポーネントスキャン」という手段を用いて自動的にDIコンテナに登録する方法。

## インジェクションの種類
① セッターインジェクション
→ コンポーネントがセッターを持つ場合、そのセッターの引数に対して依存するコンポーネントを注入する方法。
② コンストラクタインジェクション
→ コンストラクタに依存コンポーネントを直接設定する方法。(javaベース)
→ <constructor-arg>要素で参照するコンポーネントを設定する方法。(XMLベース)
→ コンストラクタに@Autowired を付与する方法。(アノテーションベース)
③ フィールドインジェクション
→ インジェクションしたいフィールドに@Autowired を付与する方法。
→ コンストラクタやセッターは不要で省略可。
納品物

[「フリーランス残酷物語 Advent Calendar 2016」](http://qiita.com/advent-calendar/2016/free_zankoku)17日目に穴が空いていたのでポエム置いておきますね。。。

私は契約書をしっかりと読む方だと思います。先方から提示された契約書のドラフト版は一字一句確認し、内容に問題があると思えば修正案を提示します。捺印用に作成される二部のうち一部は同様をしっかりと確認し、二部を重ね合わせて明かりで透かし文字に違いがないかを確認します。幸い契約内容が折り合わず仕事に結びつかないという事は一度もありませんでした。

数年前とても良い案件の紹介がありました。契約先は日本のクリエイティブ精神を代表するような大企業です。既にアプリの開発は進んでいてリリース間近ということなので開発メンバーとの打ち合わせをしたところ、アプリの内容やサーバ構成や使用言語やフレームワークなどどれもがイケてる感じだったので、これは是非とも開発をお手伝いさせて頂きたいと思い話を積極的に進めていきました。作業内容やジョインできる日取りなども決め、先方から契約書のドラフト版がメールで送られてきました。

そこで今まで見慣れない内容を見たのです。

```
納品物： DVD
```

(　ﾟдﾟ) ・・・ 

(つд⊂)ｺﾞｼｺﾞｼ 

```
納品物： DVD
```

(；ﾟдﾟ) ・・・ 
　 
(つд⊂)ｺﾞｼｺﾞｼｺﾞｼ 

```
納品物： DVD
```

（；ﾟ Дﾟ） …！？

もちろん私は先方に問い合わせます。

```
私「作業は git で行いますが、それとは別にソースコードを DVD に焼いて渡すのですね？」
担当者「はい」
私「git push を納品とすることはできないですか？」
担当者「できません」
```

きっと「[請求書に印鑑は必要ない](http://www.e-aidem.com/ch/jimocoro/entry/makino06)」問題と同じようなローカルルールが大企業にはあるに違いないと思いつつ、DVD 焼き作業はたいした時間も食わないので了承しました。毎月１日に

```
git clone git@github.com:hogehoge/fugafuga.git
```

してそれを焼くだけなので5分もかかりません。幸い DVD-RW なるものはコンビニで簡単に入手できました。どのコンビニでも売ってるので DVD って需要がかなりあるんですね知りませんでした。またまた幸い手元にある DVD ドライブ（年に1回も使わないなぁ）は DVD-R にも DVD-RW にも対応していました。Mac の CD 吸い出し用として持っていた DVD ドライブがこんなところで役に立つとは。。。

# 納品物を DVD で残す理由

さて、先方に話を聞いてみて分かったのですが、納品物を DVD として残すことの正当性はちゃんとあったのです。企業はお仕事をして売上を出して利益の一部を納税します。正しく納税されているかを管理するのは税務署です。税務署は企業が脱税していないか調査をします。「契約書／発注書／請求書／入金／納品物」あたりを揃えておけば、税務署が調査にきたときに１セットにして「これでございます。確認してください」と言えるのです。ちゃんとやってないと東芝みたいに利益をごまかすチャレンジかまして税務署に叱られたりします。

フリーランスのみなさまにおかれましては、一見不思議な契約書に出会いましても、実害がないのであれば許容して頂ければと思います。それでは良いお年を（１５日目も書いたので２回目だ）

※補足
数年前と書いたけども契約更新を何度もし、最後にDVDを納品したのは今年の4月です。ツイッターで「昔はDVDだったな」というのを見たので書いておきますね。昔のお話ではないですよー
PHPStormでCakePHP3環境のPhpUnitとFabricate設定

#PhpUnit設定

##設定
①composerにphpunitとfabricate追加して設置
![compos.PNG](https://qiita-image-store.s3.amazonaws.com/0/108475/7a812571-e458-6ffe-e366-d469e73321c0.png)

②メニューからFile->Setting->Languages&Frameworks->Php　（InterPreter追加）
Interpreterの...ボタンをクリック
＋ボタンしてremote..を選択、自分の環境に合わせて設定後「OK」クリック
![2.PNG](https://qiita-image-store.s3.amazonaws.com/0/108475/1d31ab35-2e2e-0ade-a5e6-424b89a81a59.png)
③PHPUnit設定　
![8.png](https://qiita-image-store.s3.amazonaws.com/0/108475/7a228317-f9b1-04c7-fc8c-ee4522aeaac4.png)
- Remote Interpreter追加
![9.PNG](https://qiita-image-store.s3.amazonaws.com/0/108475/27e24b7d-05dc-e990-963a-eafd5b5b900c.png)
-Path to ScriptとDefault configuration file指定
![a.PNG](https://qiita-image-store.s3.amazonaws.com/0/108475/a1030104-2d9f-8961-bd14-b395a8c8a8d7.png)
④実行
![result.PNG](https://qiita-image-store.s3.amazonaws.com/0/108475/154f4416-9e9e-c485-0d59-1c104cea15dd.png)


#Fabricate設定
以下の情報参照
https://github.com/sizuhiko/cakephp-fabricate-adaptor

- テストのためのUsersテーブル

```users.sql:
CREATE TABLE `users` (
  `id` int(11) NOT NULL,
  `name` varchar(45) DEFAULT NULL,
  `created` datetime DEFAULT NULL,
  `updated` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
```

- test\bootstrap.phpにFabricateAdaptor設定追加

```bootstrap.php:
use Fabricate\Fabricate;
use CakeFabricate\Adaptor\CakeFabricateAdaptor;

Fabricate::config(function($config) {
    $config->adaptor = new CakeFabricateAdaptor();
});
```

![fabricate.PNG](https://qiita-image-store.s3.amazonaws.com/0/108475/77f71eb0-a7b9-7edb-37af-a3383802d0ec.png)

①Bakeからモデル追加
![bake.PNG](https://qiita-image-store.s3.amazonaws.com/0/108475/fa1fe1ab-5724-5182-0ec3-fff9239bccea.png)

②UsersTableTest.phpにFabricateソース追加

```UsersTableTest.php:
<?php
namespace App\Test\TestCase\Model\Table;

use App\Model\Table\UsersTable;
use Cake\ORM\TableRegistry;
use Cake\TestSuite\TestCase;
use Fabricate\Fabricate;　　　　　　//追加


/**
 * App\Model\Table\UsersTable Test Case
 */
class UsersTableTest extends TestCase
{

    /**
     * Test subject
     *
     * @var \App\Model\Table\UsersTable
     */
    public $Users;

    /**
     * Fixtures
     *
     * @var array
     */
    public $fixtures = [
        'app.users'
    ];

    /**
     * setUp method
     *
     * @return void
     */
    public function setUp()
    {
        parent::setUp();
        $config = TableRegistry::exists('Users') ? [] : ['className' => 'App\Model\Table\UsersTable'];
        $this->Users = TableRegistry::get('Users', $config);

        //ユーザーテーブル追加
        Fabricate::create('Users', ["id" => 1, "name" => "name1"]);
        Fabricate::create('Users', ["id" => 2, "name" => "name2"]);
        Fabricate::create('Users', ["id" => 3, "name" => "name3"]);

    }

    public function testデータ確認() {
　　　　 //Fabricateから追加した10件のrandomデータが追加されたのか確認
        $data = $this->Users->find('all');

        $this->assertEquals(3, $data->count());

        foreach ($data as $row) {
            echo ' ID:' . $row->id . ' NAME:' . $row->name . '\n';
        }
    }
}

```

④データ確認
![aaa.PNG](https://qiita-image-store.s3.amazonaws.com/0/108475/a91baad2-9232-6e6c-ee3c-8b86c9d7d084.png)
フィットネストラッカーのまとめと連携方法について

#はじめに
私たちは現在、ネットワーク家電をベースとしたIoT技術に関する応用システム開発の研究を行っています。
近年の健康意識の高まりから、フィットネストラッカーと自分のシステムを連携させたいと考えました。
しかし、たくさんの会社から様々な機器が販売されており、
　・それぞれの機器でどのような値を取得できるのか？
　・システムで使用するためのAPIは提供されているのか？
　・提供されているAPIはどの程度の連携が可能なのか？
などが不透明だったので、皆さんのプログラムでも連携できるよう、
サンプルプログラムなどを踏まえつつまとめたいと思います。

#フィットネストラッカーまとめ

|機器名|種類|画面|電池持ち|防水|主なデータ|API有無|
|:--|:--:|:--:|:--:|:--:|:--|:--:|
|Jawbone UP3|バンド|LED|7日|1気圧|歩行、高精度睡眠周期、心拍|◯|
|Fitbit ChargeHR|バンド|液晶|5日|5気圧|歩行、睡眠周期、心拍|◯|
|Fitbit Charge2|バンド|液晶|5日|生活防水|歩行、睡眠周期、心拍|◯|
|Fitbit one|バンド|液晶|10~14日|生活防水|歩行、睡眠周期|◯|
|Fitbit Aria|体重計|液晶|6か月|×|体重、BMI、体脂肪|◯|
|Sony SmartBand2|バンド|LED|2日|IPX8|歩行、睡眠周期、心拍|◯|
|MISFIT SHINE2|バンド|LED|6か月|5気圧|歩行、睡眠周期|◯|
|Sleep Scan|シート|液晶|ACアダプタ|×|高精度睡眠周期、呼吸、心拍、体動|×|
|Withings Activite Steel|腕時計|アナログ|8か月|5気圧|歩行、睡眠周期|◯|
|Pebble|バンド|液晶|7日|5気圧|歩行、睡眠周期|◯|
|Moto360|バンド|液晶|24時間|IP67|歩行、睡眠周期、心拍|◯|
|Apple Watch|バンド|液晶|18時間|IPX7|歩行、睡眠周期、心拍|◯|

###APIまとめ
|機器名|SDK|主な取得可能データ|認証|
|:--|:--|:--|:--|
|Jawbone UP3|Jawbone Web API|歩行、睡眠周期、心拍|OAuth2|
|Fitbit シリーズ|Fitbit Developer API|歩行、睡眠周期、心拍|OAuth2|
|Sony SmartBand2|Lifelog API|歩行、睡眠周期、心拍|OAuth2|
|MISFIT SHINE2|Misfit APIs|歩行、睡眠周期||
|Withings Activite Steel|Withings API|歩行、睡眠周期|OAuth1|
|Pebble|Pebble SDK|加速度||
|Moto360|Wear 2.0|歩行、加速度、心拍||
|Apple Watch|watchOS 3.0|歩行、睡眠周期、心拍||
※2016/12/7時点

# サンプルプログラム用フィットネストラッカーと選定理由

サンプルプログラムを作成するにあたって、
上記の中からFitbit Charge HRとJawbone UP3を選定しました。
選定理由はどちらも心拍数の取得がAPIによって可能であることを確認し、
普及率や資料などを参考に選定しました。
どちらもOAuth認証によりAPIの利用が可能となります。

####選定参考URL
・[Data Digest: Announcing Our Annual Benchmark On The State Of US Consumers And Technology In 2015 | Forrester Blogs]
(http://blogs.forrester.com/gina_fleming/15-09-28-data_digest_announcing_our_annual_benchmark_on_the_state_of_us_consumers_and_technology_in_2015)
・[総務省｜平成27年版 情報通信白書｜ウェアラブルデバイスの種類]
(http://www.soumu.go.jp/johotsusintokei/whitepaper/ja/h27/html/nc241120.html)
####各メーカーURL
・[Fitbit]
(https://www.fitbit.com/jp)
・[JAWBONE]
(https://jawbone.com/)

#OAuthについて

OAuthは「アクセス権限付与」のためのプロトコルです。
OAuthを詳しく知りたい方は以下のURLを参考にしていただければと思います。

####参考サイト
・[OAuth 2.0 の仕様を読むために]
(http://qiita.com/awakia/items/66975de18ba25f18a961)
・[OAuth 2.0 の仕組みと認証方法]
(https://murashun.jp/blog/20150920-01.html#chapter-1)

#サンプルプログラム
選定したフィトネストラッカーのサンプルプログラムを作成しました。
以下のURLを参考にしていただければと思います。

・[サンプル1「Fitbit Charge HR + Ruby で歩数変化から家電制御」](http://qiita.com/kamira0627/private/237ccf8a4326f791b6b9)
・[サンプル2「Jawbone UP3 ＆ Node.jsで歩数をWebページに表示する」](http://qiita.com/MasaKanoMASA/private/55003453ef1f9cfcb658)

#おわりに

今回のまとめで、フィットネストラッカーと連携したシステムに興味を持つ人が増え、
この分野が更に盛り上がれば幸いです。

(作成：神奈川工科大学　杉村研究室)
一人でもできる？ソシャゲ開発・マネタイズ編 - Titaniumでソシャゲ風ゲームアプリ作った時にやったこと

遅れて超ごめんなさい。

ゲームはこれ
https://itunes.apple.com/jp/app/mamononosubako/id1156425959
https://play.google.com/store/apps/details?id=jp.ringil.mamonodev

# Webviewでも作れるよ
Javascriptがわかって、HTMLとCSSが書けて、素材とか調達できて、PHPとかRubyとかNode.jsとかPerl（実は好き）とかでサーバサイドスクリプトが書けるならTitanium MobileでクラシックなWebベースのソシャゲが作れるぞ！
別にCordovaとかでもいいんだろうけど、WebのJSからネイティブ叩いたり、ネイティブ側からWebのJS叩くのはTitaniumが楽な気がする。
資金的には、コードを全部自分で書いて、画像・音声等はフリー素材や外注で調達、サーバはGoogleのCloud EngineとCloud SQL(フェイルオーバーつき）とかでとりあえず100万円くらいあれば作れると思います！
開始して1ヶ月くらいですけど、うちはガチャオンリーで1ダウンロードあたり120円粗利があるので1万ダウンロードくらいいけばなんとか回収できると思います！継続して遊んでくださるユーザーの方々には頭が上がりません。


# Android7で今まで通りJavascriptを動かす方法教えてプリーズ
webviewで作ってもiOSではサクサク動いてネイティブのアプリのようにできます。
しかし……Androidは……。
途中までは素のWebview使ってたんですけど、Android7以降ではどうもjavascriptの挙動が変わったようで、そのまま動きませんでした。
そして、そもそもバージョンが古いとwebviewの挙動がいまいちです。
なのでTiCrosswalkモジュールを6.0.0.GA以降用に書き換えて、中のxwalk_core_libraryとかを最新版にしたら一応まぁ動いてるような気がするようになりました。でもアプリの容量がデカイ！そろそろ拡張ファイルに分けなきゃいけないめんどい！
課金処理ですが、モジュールでti.inappbillingで処理してからローカルにレシートデータを保存してサーバに送信、サーバ側でAppleやGoogleのAPI叩いて認証を行い成功したらローカルのデータを消す/失敗したらローカルのデータを保持して適切なタイミングでリトライという形を取っています。
ちゃんと認証しないと不正ツールでクラックされますよ！それっぽいのを弾いたログが一個ありました。
モジュール公開は釘を刺されましたが楽天SDKとかも頑張って導入しました。
Titaniumは頑張れば動く。モジュールを作っていくといつの間にかネイティブコードも書けるようになる。本末転倒？
コードを読む人の助けになるコメントを書くために

記事の内容はこちらを参照してください。
https://mishimay.github.io/3dc2d832b76dee85410d/
<!--

コメントを書かなくても理解できるコードは簡潔で美しいです。

しかし現実には、ライブラリのバグ対応や緊急リリースで時間が限られているなどで、その場しのぎのコードや応急処置的なコードを書かざるを得ないことがあります。

そのようなコードに何もコメントがないと、他の人や後から自分が見たときにそのコードの意図を汲み取ることが難しくなります。

場合によっては、リファクタリングの際に不必要なものとして削除されプログラムがリグレッションする可能性もあります。

そのようなことを防ぐために普段気をつけていることを紹介します。


# 「普通はこう書く」から逸脱するコードはなぜそれをするのか理由を書く
使用しているライブラリやSDKにバグがあって「普通はこう書く」というコードを書いても期待どおりに動かないことがあります。

そういうときは、一見すると稚拙で場当たり的に見えるコードを書かなければならないこともあると思います。

そのコードだけを他の人が見ると、単純に実力不足でそのような書き方になっているという誤解を与えかねません。

したがって意図してそのように書いていることをコメントで明示します。

「何をしているか」はコードからわかりますが「なぜそうしているか」はコードからはわからないので理由を書いておくことは重要です [^1]。

例

```
// xxxライブラリのバグにより期待するxxxの値が返ってこないためxxxする
```


# 参考にした記事のURLを書く
URLを書いておくメリットは多いです。

  - がんばってコメントをたくさん書くよりも参考にした記事を紹介した方が情報量が多いことがある
  - URLを書くだけなので楽
  - 文字だけでは表せない図やイラストを示せる
  - 問題の背景や他の解決方法などのより詳しい議論を知れる

以上のような理由から、参考にした記事がある場合はできるだけそのURLを書くようにしています。

URLと合わせて簡単なコメントも書いておくほうが親切だと思いますが、それすら面倒くさいとき・時間がないときはURLだけでも書いておくと良いです。少しでも情報があるのとないのとでは雲泥の差があります。

例

```
// xxxの挙動については http://stackoverflow.com/questions/xxx を参照のこと
```

# うまくいかなかった方法を書く
試行錯誤を重ねた箇所には失敗したやり方も書いておくようにしています。

あとで誰かがリファクタリングするときに「もっといい書き方がある」といって、もうすでに試した失敗する方法へ書き直してしまうのを防ぎます。

悩んだ跡を残すことで他の人に同じ轍を踏ませないようにすることができます。

うまくいかない方法を試しているときにエラーログが出た場合はそれをコピペしておくのがおすすめです。エラーログをそのままググれば情報が見つかることが多いのでどのようなエラーなのか詳しく知ることができます。エラーログは簡単に書いておける割には表せる情報量が多いです。

例

```
// xxxという方法を取ったところ「Error: xxx xxx」というエラーが出た
```

# さいごに
僕自身、何かにハマってある程度の時間を掛けて解決方法を調べた場所には上記のようなコメントを残すようにしています。

迷った痕跡を残しておくと他人にとっても将来の自分にとってもとても役に立ちますし、実際にこのようなコメントを書いておいて良かったと思ったことが何度もありました。

ぜひ参考にしてみてください。

明日は @aokis さんのポケモン話です！

---
 
[^1]: [リーダブルコード](http://amzn.to/2i1DRyQ) にそんなことが書いてありました









-->
開発をスピードアップさせるために自分がやっていること

# なぜ発表しようと思ったか
 - チームのふりかえり会では採用をテーマに扱っているため、開発効率化の話を発表・共有する場がなかった。
 - 自分がどういったマインドで仕事に取り組んでいるのか、知ってもらいたかった。
 - 同じマインドを持った人と仕事をしたい。そちらのほうが楽しいから。

----
# どうなってほしいのか
 - 日々の小さな改善をチーム全体でやっていきたい。
 - プロジェクトで決められたタスク以外に、自由に改善はやっていいと思ってもらいたい。
 - 自分のことを知ってもらいたい。

----
# 基本姿勢

----
# 基本姿勢
 - 口で語るな手で語れ。
    - http://blog.livedoor.jp/dankogai/archives/50975131.html
 - 許可より許しを求める方が簡単。
    - https://en.m.wikiquote.org/wiki/Grace_Hopper
 - 1週間勉強だけして業務を止めても、次の1週間が倍のスピードで進捗できるなら良い。

----
# どんなことをやっているのか

----
# 静的インスペクションツールを導入
## なぜやったのか
 - 機械ができる指摘は機械にやらせることで、レビューを効率的（かつ効果的）にするため。

https://scrutinizer-ci.com/

----
# Symfony3のベストプラクティスを翻訳しながら読む
## なぜやったのか
 - ベストプラクティスに沿って開発したほうが開発効率が高い。
 - 他のフレームワークでも通用するような内容も含まれていたため、参考になる（例：薄いController層）。

https://github.com/nouka/SymfonyBestPractices

----
# APIのテストの使い方を整理
## なぜやったのか
 - APIの自動テストには2つのツールを使っている（FrisbyとPhpUnit）。
 - 違うツールで同じテストを書いており、明らかに非効率的だった。

----
# 技術ミーティングでLTを3回やった
## なぜやったのか
 - たった10分程度で技術の共有ができ効率的。
 - おもしろおかしく学ぶことでモチベーションも継続しやすい（つまらないことのモチベーションを維持するコストはバカにならない）。

----
# 技術ミーティングでLTを3回やった
## どんなのをやったのか
 - 失敗から学ぶコード改善のすすめ
 - テストにまつわるエトセトラ
 - Doctrineの挙動まとめ
 - ScrutinizerCIについて

----
# 他
 - HipChatにJenkinsの自動テストの結果を流した
 - SpitzのCIUnitをフレームワークのバージョンと合わせた
 - アフィリコードプラスの開発環境をCloudFormationを使って構築した
 - hapitas_vagrantを修正した
 - Gitの設定を共有した

----
# まとめ
 - 1日のほんのちょっとの時間を使うだけでも改善はできる。
 - みんなの力を合わせれば、さらに大きな改善になるのでやりたい。
 - こんな人間ですが、友達になってください。

----
JSでグローバル汚染してる変数一覧を取得する

今、グローバル汚染してる変数はなにか？
と思ってみるとき、たぶんconsole.log(window)とかしてwindowのプロパティを見ると思います。
ただプロパティ多すぎて、どれがもともとのプロパティで、どれが汚染してる変数だ？？
となると思います。

そんな時に使えるコードです

# 用途
私は主に以下の2点の用途で使います。

1. 悪いグローバル変数を見つける
2. フレームワークやライブラリが使ってるグローバル変数を見つける

特に2番目の用途でよく使いますね。

# コード
以下を実行すればconsoleに表示されます

```js:js
console.log((function(){
  var propsOrig = [];
  var propsGlobal = {};
  var win = window.open();
  for(var i in win){
    propsOrig.push(i);
  }
  win.close();
  for(var i in window){
    if(!propsOrig.includes(i)){
      propsGlobal[i] = window[i]
    }
  }
  return propsGlobal;
})())
```

何かしらのライブラリやサンプルのコードを読んだり実際に使うときに役に立ちます。
ただwindow.openで新しく開いているのでちょっとイケてないかなぁと思っています。
もっと良い書き方がありましたら教えてくださいませ。
elm-testのテストコード改良に挑戦してみます

# あらまし
モジュール作ったらアプリケーションで実行するのは億劫なので資産残しついでにテストコードを実行しているんですが、
[elm-test](https://github.com/elm-community/elm-test)のテストコードの可読性をもう少し上げられないだろうかと、ちょっと工夫してみました。
改良というと絶対的に良くなったような表現になっちゃいますが、あくまで個人的な好みではあります:disappointed:

下記が`elm-test init`すると自動的に入ってくるサンプルコードの抜粋で、これを初期状態とします。
この中には２つのテストケースが入っていて、
両方共期待値と関数結果の２つの値の同一性を見ています。

```elm:Tests.elm(もとのコード)
all : Test
all =
    describe "Unit test examples"
        [ test "Addition" <|
            \() ->
                Expect.equal (3 + 7) 10
        , test "String.left" <|
            \() ->
                Expect.equal "a" (String.left 1 "abcdefg")
        ]
```

自分にとっては下記の要素あたりがやや作法的で、可読性を下げていたり毎回記述しなければいけない面倒さを感じさせるのかなーと思います。

- カッコ省略の`<|`
- `\() ->`の関数記述

# 変更その１: 大きい枠組みの変更

段階的に変更していこうと思います。
まず、test関数の型注釈が以下のようになってます。

```
test : String -> (() -> Expectation) -> Test
```

文字列と関数の２つの値を受け取ってTest型を返すようになっているので、
test関数のエイリアスになるような中置関数を定義してあげると`<|`を省略できそうです。
`"テスト内容" => コード`という感じになるようにしてみます。

```elm:TestExp.elm
module TestExp exposing (..)

import Test exposing (Test)
import Expect exposing (Expectation)

(=>) : String -> (() -> Expectation) -> Test
(=>) = Test.test
```

この`=>関数`をテストコードに適用してみます。

```elm:Tests.elm(v1)
import TestExp exposing (..)

all : Test
all =
    describe "Unit test examples"
        [ "Addition" =>
            \() ->
                Expect.equal (3 + 7) 10
        , "String.left" =>
            \() ->
                Expect.equal "a" (String.left 1 "abcdefg")
        ]
```

`test関数`と`<|`がいなくなって、ちょっとだけスッキリしたように感じます。

# 変更その２：空引数をとる関数の変更

次に`\() ->`を何とか出来ないかなーと。１行専有しているし。。
改めて、test関数の型注釈を見ると、２つめの引数は`()`を取ってExpectationを返すようになっているので、その構造さえ踏襲すれば変更が加えられそうです。

```
test : String -> (() -> Expectation) -> Test
```

`()`を引数に取って、呼び出す際には省略するような関数の定義パターンは下記のようなものが考えられます。

```
f : () -> Int
f _ = 100
```

```
f : () -> Int
f = \() -> 10
```

では、`Expect.equal`関数に`\() ->`記述を吸収してもらおうかなと思います。
ということで`eq`関数を作ってみました。

```elm:TestExp.elm(追記)
eq : a -> a -> () -> Expectation
eq a b _ = Expect.equal a b
```

この`eq関数`をテストコードに適用してみます。

```Tests.elm(v2)
all : Test
all =
    describe "Unit test examples"
        [ "Addition"
            => eq (3 + 7) 10
        , "String.left"
            => eq "a" (String.left 1 "abcdefg")
        ]
```

当初の課題が全部クリアになりました。
これで個人的に感じていた作法感が無くなりました！

# 変更その3：可読性もっと上がるか挑戦

v2のコードで不足感は無いんですが、
同一性を調べるという事をもうちょっとわかりやすく出来ないかということで
最後に`eq関数`を中置関数に変更してみたいと思います。
`=>`の右辺にカッコを付けなくても良いように演算優先度も調整します。

```elm:TestExp.elm(変更)
(===) : a -> a -> () -> Expectation
(===) a b _ = Expect.equal a b

infixl 8 =>
```

コレをテストコードに適用してみます。

```Tests.elm(v3)
all : Test
all =
    describe "Unit test examples"
        [ "Addition"
            => (3 + 7) === 10
        , "String.left"
            => "a" === (String.left 1 "abcdefg")
        ]
```

同一性を確認しているという事をもう少し語っているコードになったんではないかと思います。
v2とv3はどっちが良いかは好みの問題かなと。

中置関数つくる手法はJSでは出来なかったやり方なのでElmカワイイよという思いが一段と増すポイントかなと思います。
乱用するとオレオレ記号だらけのコードになると思うので、要所のみの使用がいいんではないかと。
自分は取り敢えず会社のメンバーに今回のテストコードの手法を共有し、メンバーにホクホクしてもらったv3を採用しました。
Xcode8.2はSwift2.3をサポートする最後のVersion、そして次のiOSがリリースされた時に注意すべきこと

# Xcode 8.2 リリースノートより

> Xcode 8.2 is the last release that will support Swift 2.3.

https://developer.apple.com/library/content/releasenotes/DeveloperTools/RN-Xcode/Introduction.html

# 注意すべきこと（現状を踏まえて）

- 2016年12月現在、テスト用デバイスを最新のiOS 10.2に上げてしまうと、Xcode 8.1では実機デバッグできず、8.2に上げなくてはなりません。
- 先々、iOS 10.3が出た際に、不用意にテスト用デバイスをアップデートしてしまうと、Xcode 8.3(9.0?)に上げないといけない、その時にプロジェクトがSwift 2.3の場合、サポート外になっているので困るかも？です
[JAWS-UG CLI] Lambda:#22 Permissionの追加 (CloudWatch Logs)

CloudWatch Logs に、関数を実行するためのアクセス権限を付与します。


前提条件
========


Lambdaへの権限
--------------

Lambdaに対してフル権限があること。

STSへの権限
--------------

STSに対して読み取り権限があること。


AWS CLI
-------

以下のバージョンで動作確認済

- AWS CLI 1.11.28

```bash:コマンド:
aws --version
```

```text:結果(例):
      aws-cli/1.11.7 Python/2.7.11 Darwin/15.6.0 botocore/1.4.64
```

バージョンが古い場合は最新版に更新しましょう。

```bash:コマンド:
sudo -H pip install -U awscli
```



1. 事前作業
===========


1.1. AWS IDの取得
-----------------

```bash:変数の設定:
AWS_ID=$( \
        aws sts get-caller-identity \
          --query 'Account' \
          --output text \
) \
        && echo ${AWS_ID}
```

結果(例)

      XXXXXXXXXXXX


1.2. ソースの指定
-----------------

```bash:変数の設定:
LOGS_GROUP_NAME='RDSOSMetrics'
```

```bash:変数の設定:
LAMBDA_SOURCE_ARN="arn:aws:logs:${AWS_DEFAULT_REGION}:${AWS_ID}:log-group:${LOGS_GROUP_NAME}:*" \
        && echo ${LAMBDA_SOURCE_ARN}
```


2. Permissionの追加
===================

```bash:変数の設定:
LAMBDA_STAT_ID='AllowLogs-datadog_process_rds_metrics-20161212'
LAMBDA_PERMIT_ACTION='lambda:InvokeFunction'
LAMBDA_PERMIT_PRINCIPAL="logs.${AWS_DEFAULT_REGION}.amazonaws.com"
```

```bash:変数の確認:
cat << ETX

        LAMBDA_FUNC_NAME:        ${LAMBDA_FUNC_NAME}
        LAMBDA_STAT_ID:          ${LAMBDA_STAT_ID}
        LAMBDA_PERMIT_ACTION:    ${LAMBDA_PERMIT_ACTION}
        LAMBDA_PERMIT_PRINCIPAL: ${LAMBDA_PERMIT_PRINCIPAL}
        LAMBDA_SOURCE_ARN        ${LAMBDA_SOURCE_ARN}
        AWS_ID:                  ${AWS_ID}

ETX
```

```bash:コマンド:
aws lambda add-permission \
        --function-name ${LAMBDA_FUNC_NAME} \
        --statement-id ${LAMBDA_STAT_ID} \
        --action ${LAMBDA_PERMIT_ACTION} \
        --principal ${LAMBDA_PERMIT_PRINCIPAL} \
        --source-arn ${LAMBDA_SOURCE_ARN} \
        --source-account ${AWS_ID}
```

結果(例):

      {
        "Statement": "{\"Sid\":\"AllowLogs-datadog_process_rds_metrics-20161212\",\"Resource\":\"arn:aws:lambda:\ |AWS_DEFAULT_REGION|\ :XXXXXXXXXXXX:function:\ |LAMBDA_FUNC_NAME|\ \",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"logs.\ |AWS_DEFAULT_REGION|\ .amazonaws.com\"},\"Action\":[\"lambda:InvokeFunction\"],\"Condition\":{\"StringEquals\":{\"AWS:SourceAccount\":\"XXXXXXXXXXXX\"},\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:logs:\ |AWS_DEFAULT_REGION|\ :XXXXXXXXXXXX:log-group:RDSOSMetrics:*\"}}}"
      }


3. 事後作業
===========


完了
====
[JAWS-UG CLI] CloudWatch Logs:#9 サブスクリプションフィルタの作成

前提条件
========


CloudWatch Logsへの権限
--------------

CloudWatch Logsに対してフル権限があること。



AWS CLI
-------

以下のバージョンで動作確認済

- AWS CLI 1.11.28

```bash:コマンド:
aws --version
```

```text:結果(例):
      aws-cli/1.11.7 Python/2.7.11 Darwin/15.6.0 botocore/1.4.64
```

バージョンが古い場合は最新版に更新しましょう。

```bash:コマンド:
sudo -H pip install -U awscli
```


0. 準備
===========


AWS IDの取得
-----------------

```bash:変数の設定:
AWS_ID=$( \
        aws sts get-caller-identity \
          --query 'Account' \
          --output text \
) \
        && echo ${AWS_ID}
```

結果(例)

      XXXXXXXXXXXX


0.2. ロググループの指定
-----------------------

```bash:変数の設定:
LOGS_GROUP_NAME='RDSOSMetrics'
```

1. 事前作業
===========



1.1. ログフィルタの指定
-----------------------

```bash:変数の設定:
LOGS_FILTER_NAME='datadog'
LOGS_FILTER_PATTERN=''
```


1.2. サブスクリプション先の指定
-------------------------------

```bash:変数の設定:
LOGS_DEST_ARN="arn:aws:lambda:${AWS_DEFAULT_REGION}:${AWS_ID}:function:${LAMBDA_FUNC_NAME}" \
        && echo ${LOGS_DEST_ARN}
```


2. サブスクリプションフィルタ作成
=================================

サブスクリプションフィルタを作成します。

```bash:変数の確認:
cat << ETX

        LOGS_GROUP_NAME:      ${LOGS_GROUP_NAME}
        LOGS_FILTER_NAME:     ${LOGS_FILTER_NAME}
        LOGS_FILTER_PATTERN: "${LOGS_FILTER_PATTERN}"
        LOGS_DEST_ARN:        ${LOGS_DEST_ARN}

ETX
```

```bash:コマンド:
aws logs put-subscription-filter \
        --log-group-name ${LOGS_GROUP_NAME} \
        --filter-name ${LOGS_FILTER_NAME} \
        --filter-pattern "${LOGS_FILTER_PATTERN}" \
        --destination-arn ${LOGS_DEST_ARN}
```

結果(例):

      (戻り値なし)



3. 事後作業
===========

```bash:コマンド:
aws logs describe-subscription-filters \
        --log-group-name ${LOGS_GROUP_NAME} \
        --filter-name-prefix ${LOGS_FILTER_NAME}
```

結果(例):

      {
        "subscriptionFilters": [
          {
              "filterName": "datadog",
              "destinationArn": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:datadog_process_rds_metrics-20161212",
              "creationTime": 1481613928175,
              "filterPattern": "",
              "logGroupName": "RDSOSMetrics"
          }
        ]
      }





完了
====
Yesodのセッションあれこれ

Yesodではリクエストの境界を超えて保持したいデータをセッションに格納することが出来ます。
セッションのいろいろをご紹介します。

なお本家の解説は[Yesod Book](http://www.yesodweb.com/book/sessions)をご覧下さい。

# セッションタイムアウト時間を変更する
Foundation.hsのmakeSessionBackend実装を変更すると、セッションタイムアウト時間を変更できます。

修正前）

```Foundation.hs
    makeSessionBackend _ = Just <$> defaultClientSessionBackend
        120    -- timeout in minutes
        "config/client_session_key.aes"
```

上記は120分になっています。
なお、値を 0 するとセッションが一瞬たりとも維持されなくなるので、事実上セッション管理がされなくなります。タイムアウトしなくなるわけでないのでご注意を。

# セッション管理を行わないようにする
場合によってはYesodのセッション管理を使いたくない場合があると思います。
この場合、Foundation.hsのmakeSessionBackendでNothingを返すようにします。

修正前

```Foundation.hs
   makeSessionBackend _ = Just <$> defaultClientSessionBackend
       120    -- timeout in minutes
       "config/client_session_key.aes"
```

修正後

```Foundation.hs
    makeSessionBackend _ = pure Nothing
```

# セッションをDBに格納する方法

デフォルトでは、セッション情報はファイルに格納されているようになっているので、ロードバランシングされている場合に困ることになります。
DBに格納する方法は拙作の記事[「Yesodでセッション情報をDBに格納するようにする」](http://qiita.com/jabaraster/items/758b190457f408075fc4)で紹介しているのでご覧下さい。
技術英語 > The circuitry all seems to be functioning.

@ Star Trek Voyager > THE THAW

異星人の冷凍装置の調査においてキムが

> The circuitry all seems to be functioning.

GNDピンを１つずらして実装したESP8266。基板を見ただけではall seems to be functioningのように思えたのは数カ月前の話。もちろん正常動作しない。

きちんとしたツールで解析した上で「all seems to be functioning」なのか、調査不足で「all seems to be functioning」なのか。信頼度が異なる。
PayaraをDockerで動かす

これは[Payara Advent Calendar 2016](http://qiita.com/advent-calendar/2016/payara)の19日目です。

PayaraにはDockerイメージが用意されており、Docker Hubで公開されています。

* https://hub.docker.com/u/payara/

この中から、Payara Microのイメージを使ってアプリケーションを動かすコマンドは次のようになります。

```console
docker run -d --name=helloworld -p 8080:8080 \
           -v `pwd`/helloworld/build/libs:/opt/payara/deployments:ro \
           payara/micro java -jar /opt/payara/payara-micro.jar \
           --deploy /opt/payara/deployments/helloworld.war
```

`-p`で8080ポートへアクセスできるようにしています。
`-v`でWARファイルが格納されているディレクトリ（上記では`build/libs`）を`/opt/payara/deployments`にマウントしています。
あとはイメージ（`payara/micro`）を指定して、Payara Microを動かすための`java`コマンドを書いています。

以上のように、ただでさえJAR一つで楽に動かせるPayara Microを、Dockerを使ってもっと楽に動かしてみました（JARを取ってくる必要がないので、個人的にはより楽になっています）。
Docker Hubには`payara/server-full`や`payara/server-web`、それから`payara/microprofile`もあるので、これらを使ってもう少し遊んでみようと思います。

Docker上のPayara Microを試すために作ったHello worldするだけのアプリをGitHubに置いてるので良かったら試してみてください。

* https://github.com/backpaper0/payaraac2016

以上⛄️
Pharo Smalltalkでチャットワーク（ChatWork）にメッセージを投稿したりする

Pharoからチャットワーク（ChatWork）にメッセージを投稿したりする例です。
そこそこ簡単にやれます。

## Pharoの準備
この辺から環境に応じてPharoを入手、インストールしてください。
http://pharo.org/download


## チャットワーク（ChatWork）のAPIトークンの取得の入手
認証方法 - APIトークンの取得を参考に、APIトークンを入手します。
http://developer.chatwork.com/ja/authenticate.html

リクエストしてから、1営業日ほど待つと利用できるようになります。


# ChatWork4S
ChatWork4Sは拙作のChatWork APIクライアントライブラリです。
http://smalltalkhub.com/#!/~kaminami/ChatWork4S

ChatWorkが提供するAPI利用できるAPIのすべてはカバーできてはいませんが、メッセージの投稿、取得あたりはやれます。
http://developer.chatwork.com/ja/endpoints.html

CWClientのクラス側にサンプルコードが準備されているので、まずはそちらを参照するのが良いでしょう。


## PharoへのChatWork4Sの導入
以下のスクリプトをPharoのWorkspace等でdoItして必要なライブラリを導入します。

```smalltalk
"ChatWork4Sの導入"
Gofer new
 url: 'http://mc.stfx.eu/Neo';
package: 'Neo-JSON-Core';
load.

Gofer new smalltalkhubUser: 'kaminami'
    project: 'ChatWork4S';
    package: 'ChatWork4S';
    load.

```

# メッセージ投稿
とりあえずメッセージ投稿の例です。

```smalltalk
"既存のグループチャットにメッセージを投稿"
| token roomId client |
token := 'YOUR_TOKEN'.

"グループチャットのURL https://www.chatwork.com/#!rid12345678の 12345678 部分"
roomId := 'YOUR_ROOM_ID'.

client := CWClient token: token.
client sendMessage: DateAndTime now asString  to: roomId.
```

現状、ChatWork APIには、Slackと違い、投稿時にアカウント名やアイコンを設定する機能は搭載されていないようです。
Bot用には専用アカウントを作成しないと、自分の投稿とBotの通知が区別できなくなってしまうのが、やや面倒なところです。

# メッセージ取得
グループチャットに投稿された最近100件分のメッセージを取得します。

```smalltalk
"最近100件分のメッセージを取得"
| token roomId client |
token := 'YOUR_TOKEN'.

"グループチャットのURL https://www.chatwork.com/#!rid12345678の 12345678 部分"
roomId := 'YOUR_ROOM_ID'.

client := CWClient token: token.
client allMessagesAt: roomId.
client recentMessagesAt: roomId. "前回取得分からの差分のみ取得した場合はこちら"

```

プッシュで更新分を取得できるAPIは準備されていないので、投稿されたメッセージに反応するBotを作成する場合は、Pollingで対応します。
「APIのリクエスト数は、5分あたり100回まで」の制限があるので、ご利用は計画的に。


# おわりに
Pharo SmalltalkからのChatWork API利用例でした。
RxSwift のイベントを制約してみた (Generics Extension & String Constraint)

Origami というところの Advent Calender 19日目の記事です。
本当は 12日目の記事だったはずなんですが、
旬だからという理由でここに交代をお願いされました↓
[Amazon Dash Buttonで非常ベルみたいなことをやってみた](http://qiita.com/dongri/items/47c936700aad27945822)

# はじめに
OrigamiではSwift始めたときから、MVVM　を取り入れ始めていましたが、
当初はReactiveCocoaいいんじゃね？っていう界隈の流れがありつつも、
Objective-C製からSwift製へ移行していたこともあり、
お手製のFRPっぽく書けるバイディングツールを作って使っていました。

ところが、Swiftアップデートのたびにあやしい動きを見せるReactiveCocoaにとってかわり
RxSwiftが古きから目覚め云々...

ということで、最近RxSwift使ってみています。


# RxSwift.Variable を使ってみる

RxSwiftの中でもVariableというプロパティ監視する用のやつが
好きになれそうです。
(ReactiveCocoa でいうところの MutableProperty　です)

```swift:すごいかんたんなsetup
var nameLabel: UILabel
var name: Variable<String> = Variable("dongri")

var disposeBag = DisposeBag()

func setBinding() {
  name.asObservable().subscribe(onNext: { [weak self] in
    // あたらしい値をLabelに反映
    self?.nameLabel.text = $0
  }).addDisposableTo(disposeBag)
}
```

```swift:dongriさんがdashButtonを押したので、VPにupdateします
func updateToVP() {
  name.value = "takashi"
}
```

簡単な例ですが、updateToVP()で行なっている `name.value = "takashi"`
この代入を行うとあらかじめbindされたlistenerへイベントが発火されて
nameLabel のテキストが変更されます。
ごく一般的なリアクティブなアプローチです。

ただこの代入について、よく思うことがあり、
イベント発火しすぎるのを避ける為しばしば
こう書きたくなることがあります。

```swift:
// 値に変更があったときだけ代入します
func updateToVP() {
  let VPName = "takashi"
  if name.value != VPName {
    name.value = VPName
  }
}
```

ただ、実際のViewModelではプロパティが多く、
代入に３行かけたくない。

ということでVariableを拡張してみます

# 拡張 & String制約

```swift
protocol StringConvertible {}
extension String: StringConvertible {}

extension Variable where Element: StringConvertible {

  func assignIfNeeded(_ right: String) {
    if let v = self.value as? String, v != right {
      self.value = (right as? Element)!
    }
  }
}
```

わざわざStringConvertibleを定義するのは、
StringはConcreteTypeなため、Genericsの拡張に対して制約を課せないらしい。。

そのためProtocolTypeを作ってStringにimplementしてます。

その辺は、こちらが参考になりました。
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160229/011666.html
http://stackoverflow.com/questions/39735753/swift-3-generic-extension-arguments

そのままString制約もいつかできようになるといいですね(切実)

上記の拡張を作っておくと、updateToVP() は以下のように書けるようになりました。

```swift
func updateToVP() {
  name.assignIfNeeded("takashi")
}
```

これで値に変更があった場合のみ、イベントが飛ぶようになりました。

ただ、注意しなければいけないのは、Viewの生成のタイミング如何によって
思わぬところでイベントが飛んでこないというパターンが発生するので、
初期化時にすでに取得できている値をちゃんと入れておく等の処理が必要になります。
その辺はデータの持ち方によるのでよ〜く考えてカマしてみましょう。

12日目の記事のslack通知にもこのようなロジックが入れば、
DashButtonで通知が飛びすぎなくていいですね:poop:

# We are hiring
多分採用されると思うから応募しようぜ
https://www.wantedly.com/companies/origami/projects
【D言語】std.file標準実装のslurp関数でデータを一気飲みする

#はじめに
D言語の機能をいろいろと試している初心者です．CからDに入った人なので「それ，C++でよくない？」といったこともDで書いて喜んだりしていることもありますが暖かく見守っていただけると幸いです．

#slurp
ファイル入出力，データハンドリングに関してはD言語の標準ライブラリが大いに活躍します．
今回は[std.file](https://dlang.org/phobos/std_file.html)に含まれるslurp関数を試しました．これは指定したフォーマットに則ってファイルからデータをとりあえず全部吸い上げ変数に格納してしまうというものです．Cで書こうものならこれだけでかなりの分量になってしまいそうな機能を一行で実装可能な優れものだと思います．

簡単な例として，double型のデータが並んでいる

```
100.34
145.763
198.5
  .
  .
  .
```
のようなファイルを読み込む場合，コードは


```d:
auto input_data = slurp!(double)("test.txt", "%s");
```
となります．

```
1 50.43
2 12.145
3 19.76
   .
   .
   .
```
のようにデータ番号（int）とデータ（double）が並んでいるようなテキストを読み込む場合は，

```d:
auto input_data = slurp!(int, double)("test.txt", "%s %s");
```
このようになります．!(Types...)でデータを格納する際の型を指定，続く(string *filename*, string *format*)で読み込むファイルとフォーマットを指定します．データを格納する変数の型をautoで宣言できることや異なる型のデータをタプルとして束ねられることといったD言語の特徴が活きています．
input_data変数はデータ型が一つだけのときは与えられた型の配列に，複数あるときはタプルの配列（※タプルの配列，という表現が厳密に正しいのか不安．間違っていたらご教授願います）になります．

格納したデータへは添字でアクセスできます．

```d:
writeln(input_data[0]);
```

```:出力
100.34    //値の配列の場合

Tuple!(int, double)(1, 50.43)    //タプルの配列の場合
```


タプルなので，それぞれ要素に名前をつけることができます．データの各要素へのアクセスがしやすくなります．

```d:
auto input_data = slurp!(string, "name", int, "age")("test.txt", "%s %s");
for(int i=1; i < input_data.length; i++){
	writeln(input_data[i].name);
}
```

#iCalendarへの出力へ第一歩
タスク管理ツールで作成したタスクをiCalendarに同期するツールを作っています．具体的な内容については自分のブログの方で記事にするつもりです．以前にもテキストファイルからデータを読み込み別のフォーマットに変換して出力するプログラムをDで書いたたことがありますが，非常にシンプルに書けるのでstd.fileライブラリはありがたいですね．