OmniAICreator/Qiita-1.07M huggingface dataset:
Inventory / unity > code v0.1 > Row:Prev/Next, Column:Prev/Nextボタン実装

```txt:動作確認
Unity 5.3.5-f1 on MacOS X El Capitan
```

関連　http://qiita.com/7of9/items/523a9ec838eaae05bcc1

## v0.1 機能

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/c30f2608-45d6-a670-c859-4fefeac138b3.png)

Row, ColumnのPrev/Nextボタンの実装。
今のところダミーデータを使用。

## code v0.1

[v0.1 @ github](https://github.com/yasokada/unity-160820-Inventory-UI/releases/tag/v0.1)

### SampleData.cs

ダミーデータ読込み用。

```SampleData.cs
using UnityEngine;
using System.Collections;

namespace NS_SampleData
{
	public static class SampleData
	{
		// 1: caseNo
		// 2: row
		// 3: column
		// 4: name (key)
		// 5: about
		// 6: datasheet URL (TODO)

		public static string GetDataOfRow(int row) {
			switch (row) {
			case 0:
				return "1,1,1,MAX232,The MAX220-MAX249 family of line drivers/receivers is ...";
			case 1:
				return "1,1,2,MAX44242,The MAX44242 provides a combination of high voltage, low noise, low input ...";
			}
			return "";
		}

		public static string GetDataOfColumn(int clm) {
			switch (clm) {
			case 0:
				return "1,2,1,HC-SR04,Power supply: 5V DC. Ultrasonic Frequency: 40k Hz\n• Resolution: 1 cm ...";
			case 1:
				return "1,2,2,MPL115A2,an absolute pressure sensor with a digital I2C output targeting low cost applications...";
			}
			return "";
		}

	}
}
```

### InventoryCS.cs 

メインの処理。

```InventoryCS.cs
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using NS_SampleData;

/*
 * v0.1 2016 Aug. 21
 *   - add MoveColumn()
 *   - add MoveRow()
 *   - add SampleData.cs
 *   - add UI components (unique ID, Case No, Row, Column, About, DataSheet)
 */

public class InventoryCS : MonoBehaviour {

	public InputField ID_uniqueID;
	public Text T_caseNo;
	public Text T_row;
	public Text T_column;
	public InputField IF_name;
	public Text T_about;
	string datasheetURL;

	void Start () {
		T_about.text = NS_SampleData.SampleData.GetDataOfRow (0);	
	}
		
	void Update () {
	
	}

	public void MoveRow(bool next) {
		if (next == false) { // previous
			T_about.text = NS_SampleData.SampleData.GetDataOfRow (0);	
		} else {
			T_about.text = NS_SampleData.SampleData.GetDataOfRow (1);
		}
	}

	public void MoveColumn(bool next) {
		if (next == false) { // previous
			T_about.text = NS_SampleData.SampleData.GetDataOfColumn(0);
		} else {
			T_about.text = NS_SampleData.SampleData.GetDataOfColumn (1);
		}
	}
}
```
Rubyに触れてみる(*‘ω‘ *)

#**Ruby**ってどんな感じ？
###**Ruby**って何？
- **Ruby**という言語はざっくりと言うと、まつもとゆきひろ氏が**たのしくプログラミングができる**ようにと開発してくださったプログラミング言語ですね。

　これまで私は授業でC言語を使っていたのですが、初めてRubyに触れたときは楽しすぎてPCの前で小躍りしそうなくらいでしたね(笑)
　えぇ、実際に立ち上がって、意味もなくクルクルと回り始めちゃいましたけど(/ω＼)ｴﾍﾍｯ
　　　　　
　**それほどに楽しいのがRubyなんですね！**

###なぜそんなに**楽しいと思った**のか？
- 私、これまでC言語を使っていましたが、それに比べてRubyはとっても**ラク**ができるわけです。
　開発者のまつもとゆきひろ氏が
 
> **Rubyには、プログラミングを書くことを楽にするための秘密が詰まっています。熟練プログラマである私が作った「自分が楽にプログラミングをするための工夫」でいっぱいです。**

> *ソフトバンク　クリエイティブ株式会社「たのしいRuby　第２版　Rubyではじめる気軽なプログラミング」監修者まえがき　より*

とおっしゃっているように、Rubyはプログラムを書くのが**ラク**なわけですね。

プログラミングを始めるうえで、一度は書くであろうプログラムであるHello world を画面に出力するプログラムをRubyとC言語で書いてみて比較してみたいと思います。

**まずはC言語**

printf関数というものを使って出力します


 　　`printf  ("Hello world");`  

これでも一行だし、そんなに大変じゃないじゃんって思いますよね？

**次にRubyです**

putsメソッドというものを使います（Rubyでは関数を使わず、代わりにメソッドというものを使います）

　　`puts  "Hello world"`

**なんと、Rubyになって（）も；も無くなってしまいました！**

実際にC言語でプログラムを書いたことがある人にはわかっていただけるのではないかと思いますが、**（）**ってつけるのが面倒だったり、よく**；**を付け忘れたりしませんか？

でも、Rubyなら**（）**も**；**も省略できてしまうんです！
**；**を付け忘れてエラー箇所を探すこともありません！

**これって、すごいことだと思いませんか？**

C言語を使っていたら、打たなければならなかった文字を打たなくてもよくなり、エラーを探す時間も短くなりますよね。これは時間の節約にもなりますし、それだけすぐにプログラムを書きあげられるようになるということにも繋がるわけですね。

 > **Rubyを作っているのも究極的に言うと、効率よく生産性よく作れるようにすることで、「プログラミングをつまらないと思う人たちはもういいよ。僕らだけで作るから」、そう言える世界を作りたいと内心で思っているからなんです。**
 > http://type.jp/et/feature/243 
まつもとゆきひろ氏が「生涯プログラマー」でやっていきたい若手に贈る3つの言葉 より
↑お時間があればこちらの記事を読まれてみるとためになるかと思います(-ω-)/
私も何度も読み返しております(笑)

###**Rubyに触れてみる！**
何よりも実際に触ってみることが一番手っ取り早いと思いますので、
paizaでCとRubyを比較してみてください(*- -)(*_ _)ペコリ

https://paiza.jp/works

このサイトではC言語の講座とRubyの講座の両方がありますし、**webページ上で自分の描いたプログラムを実行**することができますのでオススメです(-ω-)/

C言語を軽く学習した後にRubyを学習してみると「あぁ、ラクだなぁ( *´艸｀)」ってなると思います(笑)
興味のある方はぜひ学習されてみることをおすすめいたします。
Ubuntu 16.04LTSで、sshログインできない対策

Ubuntu 16.04LTSをいれたら、sshの公開鍵認証でログインできなくなった。
/var/log/auth.log を確認したところ、下記のエラーが出力されている。
OpenSSH-7.0でssh-dssは無効化されたようだ。

```shell-session
Aug 20 23:36:26 ubuntu sshd[25608]: userauth_pubkey: key type ssh-dss not in PubkeyAcceptedKeyTypes [preauth]
```

参考: http://www.openssh.com/txt/release-7.0

プロトコルの脆弱性を把握できてなかったことに衝撃を受けつつ調べるとこの情報を見つける。
参考: http://security.stackexchange.com/questions/112802/why-openssh-deprecated-dsa-keys

ssh-dssを再有効化するのはありえないので、ECDSAへの移行を決心する。ssh-keygenで、鍵ペアを生成。

```shell-session
% ssh-keygen -t ecdsa -b 384 -C 'sumikawa@XXX'
Generating public/private ecdsa key pair.
Enter file in which to save the key (/Users/sumikawa/.ssh/id_ecdsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /Users/sumikawa/.ssh/id_ecdsa.
Your public key has been saved in /Users/sumikawa/.ssh/id_ecdsa.pub.
The key fingerprint is:
SHA256:XXX sumikawa@XXX
The key's randomart image is:
+---[ECDSA 384]---+
(snip)
+----[SHA256]-----+
```

これで無事sshログインできるようになりました。

ついでにgithubとbitbucketのSSH keysも更新。どっちもECDSAを受け付けてくれた。
iPadのpromptアプリは未対応だった。残念。
技術ブログはじめました(-ω-)/

#主に**Ruby**と**Ruby on rails**についての情報を発信します！

- 基本的には日々の学習の記録や、プログラミングに関する情報を発信していきます。
- ブログのようなものを書いたことがないので、お見苦しい文章となるかと思われますが、
改善できるように日々努力しますのでご容赦くださいm(__)m　

- 私自身、C言語を授業で少し進めた程度の**プログラミング初心者**ですので、 中、上級者の読者様のお役にはあまり立てないと思います。
- 初心者の私がつまづくところが、初心者の方が**同じようにつまずくところ**なのではないかと思いますので、解決までを参考になるように記述していきたいと思います。
私と同じように**プログラミングを始めたばかりの方**や、これから**始めてみようと思う方**のお力に少しでもなれるように頑張りますので、よろしくお願いします(*- -)(*_ _)ペコリ
まず、ブログの書き方を学ばねばなりませぬが...(;´･ω･)

![alt](http://3.bp.blogspot.com/-VL3mIS37t3I/VwIjMbe20hI/AAAAAAAA5gM/uko5NAJWu6I5-RMOnu9L1FUl0jRlRmI8w/s800/pasokon_kyoushitsu_woman.png)
サクラエディタ設定メモ

# サクラエディタ設定メモ

## 概要
社内ではvimが使えないためサクラエディタで生活しようと思う。
サクラエディタをインストール後から快適に過ごすためのtipsをまとめていく。

## 1. 表示
設定タブから以下を表示する。機能の説明は省略。

* ツールバー
* タブバー
* ステータスバー
* ミニマップ

## 2. カラー
インストール後のデフォルトのカラーも見づらいわけではないが試しに導入。

1. solarizedの設定（拡張子を指定する場合）
今回は .txt のみ色を変えるように設定を反映。
  1. カラーファイルは以下のものを使わせていただく  
[tsuyoshicho/solarized dark.col](https://gist.github.com/tsuyoshicho/a06b315e8ee952929763)
  2. solarized のカラーファイルを .colとして保存  
  3. サクラエディタの設定フォルダに置く  
     フォルダの場所は他にも.colファイルがあるところ
  4. タイプ別設定一覧から新規で以下を作成  
     * solarized dark
     * solarized light
  5. 作成した設定変更から以下を設定  
     * スクリーンタブのファイル拡張子かに「txt」を入力
     * カラータブのインポートから先ほどDLした.colファイルをそれぞれインポート
  6. 適用するカラーの優先度を変更する  
     タイプ別設定一覧からsolarized darkまたはlightをデフォルトでインストールされている「テキスト（txt,log,1st,err,ps）より上に来るようにする
  7. 完了


2. solarized設定（拡張子を指定しないデフォルト設定にする場合）
  1. 上記１の手順確認後以下を行う
  2. タイプ別設定一覧の「基本」を複製
  複製後、基本２が生成される（デフォルトに戻すためのバックアップ用）
  3. 基本の設定変更から以下を設定
   * カラータブのインポートから適用したい.colファイルをインポート
  4. タイプ別設定一覧で、カラー設定した基本１が基本２の上に来ていることを確認
  5. 完了
[Swift] テストの実行時にプロダクトコードを実行しないようにする


テストを書いて、XCTest を実行してみるとユニットテスト以外にもアプリが起動しますよね。

他の言語のユニットテストフレームワークだとそんなことはないのですが、XCTest の場合テスト実行とともに application(application:didFinishLaunchingWithOptions) が呼ばれます。

テスト実行時にアプリの起動時のコードも実行されると無駄なログが発生したり、テストを正しく実行できません。

## テスト実行中かどうかを判定する

テストの実行中かどうかはテストの実行環境にのみ存在する Class があるかどうかで判定できます。
テストの実行環境にのみ存在する Class とは XCTest Class などがあります。

```swift
    func isTesting() -> Bool {
        return NSClassFromString("XCTest") != nil // nil じゃなかったらテスト実行中
    }
```

#### 2016/08/21 23:48追記

※これはXcode7まで
@mono0926 さんからコメントいただきました。↑の例とは別に判定する方法があるそうです。

```swift
    func isTesting() -> Bool {
        return NSProcessInfo.processInfo().environment["XCInjectBundle"] != nil
    }
```

#### 2016/10/28 23:38追記

ProcessInfoを使う場合 Xcode8 から判別方法が変わったようです。

```swift
    func isTesting() -> Bool {
        return ProcessInfo.processInfo.environment["XCTestConfigurationFilePath"] != nil
    }
```

## テスト実行中の場合処理をスキップする

この判定を application(application:didFinishLaunchingWithOptions) の先頭において、もしテスト中だと何もしないコードを入れます。本番環境に（テスト専用の）不要なコードが入るのはイヤなので #if DEBUG など、リリース時にはコードが含まれないようにするといいと思います。

```swift
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
		#if DEBUG
        guard !isTesting() else { // テスト実行中なら
            window?.rootViewController = UIViewController()
            return true
        }
        #endif
    }
}

extension AppDelegate {
    func isTesting() -> Bool {
        return NSClassFromString("XCTest") != nil
    }
}
```
HubotでWeather APIを使って天気を教えてくれるやつを作った

[HubotでHotpepperグルメサーチAPIを使ってお店を紹介してくれるやつを作った](http://qiita.com/kmurae/items/87fb6d5b9b95d2511edc)の続きです。

天気予報も知りたいなと思って作ってみました。
今回天気予報の取得には[OpenWeatherMap](http://openweathermap.org/)のWeather APIを使いました。
今回もSlackと連携することを想定しています。

## APIキーの取得
[Sign Up](https://home.openweathermap.org/users/sign_up)に必要情報を入力してAPIキーを発行する。[price-list](http://openweathermap.org/price)に色々プランがあるけど、勉強のためなので、Freeで十分。
登録が済むとAPIキーが発行されます。

## 使ってみる
完成形を先にお見せします。

```
# Description:

module.exports = (robot) ->
  robot.hear /(.*)の天気は？/i, (msg) ->

    cityName  = msg.match[1]
    query = encodeURIComponent msg.match[1]

    request = msg.http("http://api.openweathermap.org/data/2.5/forecast/weather?q=#{query}&APPID={APIキー}")
    .get()
    request (err, res, body) ->
      json = JSON.parse body
      switch json["list"][0]["weather"][0]["main"]
        when "Clear"
          weather = "晴れ"
        when "Clouds"
          weather = "くもり"
        when "Rain"
          weather = "雨"
        when "snow"
          weather = "雪"

        icon = json["list"][0]["weather"][0]["icon"]

      msg.reply "#{cityName}の天気は#{weather}です \n http://openweathermap.org/img/w/#{icon}.png"
```

### 説明
```
module.exports = (robot) ->
  robot.hear /(.*)の天気は？/i, (msg) ->
```
「◯◯の天気は？」というフレーズに反応して処理を実行します。◯◯の部分に調べたい地名を入力します。

```
cityName  = msg.match[1]
query = encodeURIComponent msg.match[1]
```
(.+)でマッチした文字列をエンコードしています。

```
request = msg.http("http://api.openweathermap.org/data/2.5/forecast/weather?q=#{query}&APPID={APIキー}")
    .get()
```
APIをたたきます。
`weather?q=#{query}`でエンコードされた地名をAPIに渡してます。

```
json = JSON.parse body
      switch json["list"][0]["weather"][0]["main"]
        when "Clear"
          weather = "晴れ"
        when "Clouds"
          weather = "くもり"
        when "Rain"
          weather = "雨"
        when "snow"
          weather = "雪"
```
返ってきたJSONに対して処理を書きます。
`json["list"][0]`で今日のデータを取得します。さらに`["weather"][0]["main"]`で天気を取得します。
Weather APIでは天気が英語で返ってくるので、文字に応じて日本語を返します。


```
icon = json["list"][0]["weather"][0]["icon"]
timestamp = (new Date()).toISOString().replace(/[^0-9]/g, "")
```
`json["list"][0]["weather"][0]["icon"]`によって天気アイコンは変わってるみたい。
`"01d", "01n"`のd、ｎは、d:day、n:nightの略っぽい。
また、Slackでは２回目以降の画像はサムネイルとして表示されないようなので`timestamp = (new Date()).toISOString().replace(/[^0-9]/g, "")`を画像名の最後に出力します。

あとはそれを
`msg.reply "#{cityName}の天気は#{weather}です \n http://openweathermap.org/img/w/#{icon}.png?#{timestamp}"`
で出力してやればOK

ではではやってみます。

```
mybot> 那覇の天気は？
mybot> 那覇の天気は晴れです
 http://openweathermap.org/img/w/02d.png?20160820234350565
```

いい感じでできました。
railsでオブジェクトをnewできないエラー

#事象
rails consoleから単純にnewしたら以下のエラーが表示される。
```irb(main):004:0> s = Skill.new
NoMethodError: undefined method fetch_value for nil:NilClass
```
```
irb(main):007:0> s = Skill.new
NoMethodError: undefined method finder_needs_type_condition? for nil:NilClass
```
なんでnewが、undefindメソッドなんだろうと悩む。

skillsテーブルの定義内容は以下です。
mysql> show columns from skills;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| name        | varchar(255) | YES  |     | NULL    |                |
| class       | varchar(255) | YES  |     | NULL    |                |
| change_flg  | tinyint(1)   | NO   |     | 0       |                |
| created_at  | datetime     | NO   |     | NULL    |                |
| updated_at  | datetime     | NO   |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
8 rows in set (0.01 sec)


#原因
***カラム名が予約語***
少し慣れている人であれば上のテーブル定義からすぐにわかると思いますが、
classがrubyの予約語です。
予約後をカラム名として利用すると発生するうようです。


#対応
テーブル定義を変更しましょう。
・マイグレーションファイルを作成
```
$ rails g migration RenameSkillsClassColumn
      invoke  active_record
      create    db/migrate/20160819115043_rename_skills_class_column.rb
```
・マイグレーションファイルの中身を編集
```
class RenameSkillsClassColumn < ActiveRecord::Migration
  def change
  	rename_column :skills, :class, :skill_class
  end
end
```

・migrateの実行
```
$ bundle exec rake db:migrate
```


rails console上で再度newしてみると
```
irb(main):034:0> s=Skill.new
=> #<Skill id: nil, name: nil, skill_class: nil, change_flg: false, created_at: nil, updated_at: nil, type: nil, user_id: nil>
```

ちゃんとnewできました！初心者は、こんなのでも時間をロスしてしまいます。

#参考
[StackOverflow](http://stackoverflow.com/questions/32761577/rails-dbseed-error-undefined-method-finder-needs-type-condition-for-nilnil)
[予約後一覧](http://www.trail4you.com/TechNote/Ruby/Rails_keyword_list.html)
www.webopixel.net/php/753.html自分用魚拓

www.webopixel.net/php/753.html

PHPUnitでテストしよう。IntelliJ（PHPStorm）でも実行できるようにしてみた
Posted: 2013.05.20 / Category: PHP 

そろそろテストとかお勉強しないとなと思ったりしたのでとりあえず PHPUnit を導入して、簡単なコードのテストを書くとこまでやってみます。
ついでにIntelliJ（PHPStorm）でも実行できるように設定してみました。

環境はWindows7でPHPはXAMPPで入っています。
PHP 5.4 / PHPUnit 3.7

PHPUnitのインストール

PHPUnitはPEARからインストールします。
PHPの環境変数が設定していない場合は「C:\xampp\php」で設定しておきます。
管理権限でプロンプト（ターミナル）を起動します。
まずはPEARのアップデート。

pear upgrade PEAR
続いてPHPUnitのインストール。

pear config-set auto_discover 1
pear install pear.phpunit.de/PHPUnit
使ってみる

インストールが終わったので、早速プログラムのテストをしてみましょう。
テストするためのPHPファイルを「Hello.php」という名前で作成します。

Hello.php
?
1
2
3
4
5
6
7
8
9
<?php
class Hello
{
    public function getMessage()
    {
        return "hello world";
    }
}
プロンプトで「Hello.php」を作成したディレクトリをカレントにします。

テストコードのひな形を自動作成

テストコードのひな形を自動作成するためのPEARをインストールします。

pear install phpunit/PHPUnit_SkeletonGenerator
インストール完了後次のコマンドを実行します。

phpunit-skelgen --test Hello
「HelloTest.php」というPHPファイルが作成されます。
まずは「PHPUnit/Autoload.php」とテストするファイル「Hello.php」を読み込みます。

HelloTest.php
?
1
2
3
4
<?php
require_once 'PHPUnit/Autoload.php';
require_once 'Hello.php';
ソースの一番下には「Hello.php」で実装した「getMessage」をテストするためのメソッド「testGetMessage」がありますので、下記のようにします。

HelloTest.php
?
1
2
3
4
5
public function testGetMessage()
{
    $this->assertEquals("hello world", $this->object->getMessage());
}
「assertEquals」メソッドは2つの引数が等しいことを検証します。
「getMessage」は「hello world」という文字列を返しますので、テストは通るはずです。
下記コマンドでテストを実行します。

phpunit HelloTest
「OK (1 test, 1 assertion)」と表示されればテストは問題なかったということです。

IntelliJ（PHPStorm）でテストできるようにする。

「File」->「Setting」でSettingウィンドウを表示したら「PHP」の項目を選択。
「Interpreter」でPHPを選択します。



「Run」->「Edit Configurations」でClassを下記のようにするか、Directoryを選択します。



あとは「Run」ボタンでテストが実行されます。

これくらいのコードだったら全然大丈夫なのですが、フレームワークとかのテスト書こうと思うといきなり難易度高くなりませんかね。さてどうしたもんでしょ。

参考サイト

PHPUnit Manual
第1回 PHPUnitの概要と導入 | Think IT
http://www.findxfine.com/programming/php/995557148.html
パフォーマンスを意識したjQueryの記述方法



##参考
以前、jQueryのセレクタに関してまとめたので参考までに  

[http://qiita.com/Rock22/items/66b7be754034412b8851](http://qiita.com/Rock22/items/66b7be754034412b8851)
  
  
##セレクタの速さを意識する

  
1.idセレクタ

	$('#id');  // 裏でgetElementById()が処理をしている

2.タグセレクタ
  
	$('div');  // 裏でgetElementsByTagName()が処理をしている
  
3.classセレクタ  

	$('.class');  // 裏でgetElementsByClassName()が処理をしている
  
`id`属性は原則、1ページに一つしかないため、`id`セレクタを使用した場合
指定の要素を取得できた段階で以降のチェックを行わないため、負荷が軽く済み
`class`属性は1ページに複数存在する可能性があるため、最後までチェックを行います。
ですので`id`セレクタと比べ処理時間が長くなります。

ページに一つしかないものは`class`ではなく`id`属性を付与した方が高速化という意味では妥当だと思われます。
もし取得したい要素に`id`が付いている場合は`id`を指定し、付いていなくても親要素や、そのまた親の要素から`id`で辿るような記法をするのが良いでしょう。
上記の`class`をそのように取得する場合、下記のようになります。  
  
	$('#id div.class');  
  
  
##無駄なObjectを生成しない  

jQueryオブジェクトの作成には負荷がかかるので下記のような実装を用いる

悪い例  
	  
	for (i = 0; i < 1000; i++) {
		$("#id div.class").append(' ' + i);
	}  
  
良い例  
  	
  	var test = $("#id div.class");
	for (i = 0; i < 1000; i++) {
		test.append(' ' + i);
	}    
  
##メソッドチェーンを活用する

jQueryのメソッドは、jQueryオブジェクトを受け取ってjQueryオブジェクトを返すようになっているものが多いので、
何度も同じオブジェクトへの参照を回避するため、一つの処理の後にまた別の処理をつなげて書く「メソッドチェーン」を活用すると良い  
  
悪い例
	
	$('.class').addClass('box');
	$('.class').css('background-color', 'black');
	$('.class').css('color', 'white');
	
	
良い例  

	$('.class').addClass('box').css('background-color', 'black').css('color', 'white');  
  
  
##終わりに

今まで、とりあえず想定のDOM操作が行えていればOKという感じで実装していたので、
パフォーマンスという点に関してはあまり深く考えていませんでしたが、業務で無駄なコードを指摘されることが多かったので、今回調べてみました。  
他にもパフォーマンス改善のためできるテクニックは沢山あるようなので、随時更新していきたいと思っています。
JavaEE7のスコープ(CDI)についてメモ


|アノテーション|スコープ|パッケージ|備考|
|:--|:--|:--|:--|
|`@Dependent`|注入先のBeanのスコープに従う|`javax.enterprise.context`|デフォルト設定|
|`@RequestScoped`|ユーザとWebアプリケーションの単一のHTTPリクエスト間|`javax.enterprise.context`|
|`@SessionScoped`|ユーザのWebアプリケーションの複数のHTTPリクエスト（セッションが有効な）間|`javax.enterprise.context`|
|`@ApplicationScoped`|アプリケーションの開始から終了までの間|`javax.enterprise.context`|
|`@ConversationScoped`|リクエスト以上セッション以下の範囲で、開始・終了をアプリケーションで明示する|`javax.enterprise.context`|
|`@ViewScoped`|1つのViewが表示されている間|`javax.faces.view`|JSF専用|
|`@FlowScoped`|複数Viewの中で範囲を明示する|`javax.faces.flow`|JSF専用|

##注意点
CDIと同名のアノテーションがJSFのにも存在しているので、注意が必要。
私も実装する際、混同しそうになったので参考までに記載しておきます。

- `javax.faces.bean.RequestScoped`
- `javax.faces.bean.SessionScoped`
- `javax.faces.bean.ApplicationScoped`
- `javax.faces.bean.ViewScoped`
Nginx + Spring Boot(Tomcat)でアップロードサイズ超過時のエラーレスポンスが遅延する

今携わっている案件で、ファイルアップロード時にサイズ超過エラーが発生するとエラーレスポンスが遅延する事象にぶちあたってしまいました。実はかなり前からぶちあたっていたのですが、いよいよ最終的な対応方法を決めないといけなくなってきたので、ちょっとだけ真面目に調べてみました。


# 事象
事象としては、リクエストしてから約60秒後にエラーレスポンスが返却された・・・。ログを見る限りではアプリ的にはもっと早く検知しているのですが・・・。
この事象はどうやら分割レスポンス（`Transfer-Encoding: chunked`）の時に発生するようで、ためしにJSON文字列(`Content-Length`がある状態)で返却したら遅延は発生しませんでした。この事象が発生したアプリでは、エラーレスポンスをSpring MVC+Jacksonの仕組み(`HttpMessageConverter`)を使ってJavaBean->JSONにしていたため、分割レスポンス扱いになります。
どこで処理が止まっているのかデバッグ実行して調べてみたところ・・・サイズ超過検知後に残りのリクエストデータを読み込む処理のところで処理が止まっていました。どうやら・・・NginxとTomcatがお互いにデータの読み込み待ち状態になってしまい、Nginx側のタイムアウト(デフォルトだと60秒)検知をトリガーにそれぞれ処理が再開した模様・・・ :disappointed_relieved: 


# Spring(Spring Boot)アプリ

アップロード用のコントローラはこんな感じ。
 
```java
@RestController
public class FileUploadRestController {

    @RequestMapping("/files")
    String upload(MultipartFile multipartFile) {
        return multipartFile.getOriginalFilename();
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.PAYLOAD_TOO_LARGE)
    public ApiError handleMultipartException(MultipartException e) {
        ApiError error = new ApiError();
        error.setCode("UPLOAD_SIZE_ERROR");
        return error;
    }

}
```

エラー時のJSONを表現するJavaBeanはこんな感じ。

```java
public class ApiError implements Serializable {
    private String code;

    public String getCode() {
        return code;
    }
}
````

Spring MVCの例外ハンドラでエラー検知できるようにするために、マルチパートリクエストの解析を遅らせるようにします。

```java

@Configuration
public class WebMvcConfig {
    @Bean
    StandardServletMultipartResolver multipartResolver() {
        StandardServletMultipartResolver resolver = new StandardServletMultipartResolver();
        resolver.setResolveLazily(true); // trueを指定すると解析を遅延させることができる
        return resolver;
    }
}
```     

なお、上記アプリコード（本事象の検証用に使用したアプリ）はGitHubに公開してあります。

* https://github.com/kazuki43zoo/nginx-springboot-demo



# 原因は？

本質的な原因なのかはかなり怪しいですが・・・・ :sweat: 
Nginxがバックサーバーにプロキシする際のHTTPバージョンが1.0（Nginxのデフォルト値のまま）だったことが、この事象を引き起こしていました。分割レスポンスはHTTP 1.1でサポートされた仕組みなので、Tomcat側で行う処理がHTTP 1.0向けになったことで期待通りの動きにならなかったみたいです。（なんとなく、Tomcat側にも何かしらの問題があるような気はするが・・・）


# Nginxのプロキシ時のHTTPバージョンを1.1にする

プロキシ時のHTTPバージョンの指定は、[`proxy_http_version`](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_http_version) を使用します。

```text
http {
    # ...
    upstream spring-boot {
        server springboot:8080;
    }
    # ...
    server {
        listen       80;
        server_name  localhost;
        # ...
        client_max_body_size  100m;
        # ...
        location / {
            proxy_pass http://spring-boot/;
            proxy_http_version 1.1; #### これを追加 ###
        }
        # ...
    }
    # ...
}
```

# まとめ

たぶん、ぶちあたっていた事象は解決しそうだが・・・・なんかモヤモヤ感がとれないな〜 :sweat_smile:
今のプロジェクト・・・Nginxに詳しい人がいないけど、なぜか使っているw
JSONって書いてあるのにJSONじゃない形式のデータを内閣官房なる組織が公開していたから、pythonでJSON形式のデータの保存する方法をまとめる

（【追記】コメントにあるようにgc373さんのご協力で、問題のデータはJSONとして修正されています。）
データは大切です。優れたデータは社会によい価値を提供するでしょう。優れたデータというのは、価値の高い情報を持っているだけでなく、それが扱いやすいということも大切でしょう。扱いやすいというのは、データに簡単にアクセスでき、そのデータを容易に読み込めるということでしょう。特別なソフトウェア用の形式であったり、余計なものが書かれていて読む前に人間が読まないといけないというのは扱いづらいと言えるでしょう。SHIFT_JISなのも困りものです。

とはいえ、まずはデータがあって初めて何かができるわけで、オープンデータとして、政府がデータを公開し始めているのは評価すべきことのはずです。しかし、どのような状態のデータを公開すると良いのかについてはノウハウが不十分におもわれます。

さて、[http://www.data.go.jp/](http://www.data.go.jp/)というサイトがあり、無数のデータが手に入るようです。きっと、我が国を良くすることができるデータが埋もれているに違いありません。・・・と期待をして、ちょっと触ってみました。とりあえず、[メタデータ一覧2016年7月分](http://www.data.go.jp/data/dataset/cas_20160704_0005)というのが目に入ったので、どんなことが書いてあるのか気になったので、JSONのものをダウンロードしました。

```py
import json
text = "".join(open("hoge.json").readlines())
data = json.loads(text)
```

のようにすれば、読み込めるでしょう。そのはずでした。しかし、上手く行かないわけです。仕方がないので、ファイルをちょっと覗いてみました。すると、なんということでしょう。

```
[{u'license_title': None, u'maintainer': None, ・・・
```

JSONはjavascriptの形式に沿ったデータです。しかし、javascriptにはNoneなんてものはありません。u'hoge'のような文法もありません。ええ、これはJSONではないのです。

むしろ、Noneとかはpythonでしょう。ひょっとするとこれはpythonのデータをjsonに変換することなく出力してしまったのではないかという疑惑が起きてきました。ということで、危険を顧みず、

```py
data = eval(text)
```

してみたところ、データがエラーなく読み込めるではないですか。もちろん、この方法はとても危険です。悪意のある部分が含まれていたらひとたまりもないでしょう。政府が出しているデータだから大丈夫と言っていいものでもないですが、何かあったら政府のせいにすることにして実行しました。よい子は真似してはいけません。実際、CPUの使用率は100%になり、16Gのメモリも使いきるという状況になりました。

さて、せっかく読み込めたデータを今度こそJSONで保存しましょう。

```py
with open("out.json", "w") as f:
    f.write(json.dumps(data))
```

これで無事jsonとして保存できました。めでたしめでたし。

これで終わって、意見受付のところにでも、間違ったデータだと文句をつけておこうかと思ったのですが、意見受付のリンクを踏むと「安全な接続ではありません」となって修正の要求もできない。ということでここにこんなことを書いたと。

どこかにイキのいいデータは落ちてないものか・・・
Hubotからslackに画像を投稿してみる

ある時、突然こんな要望をされて困った。
「猫」って発言されたらこの画像を表示したい！
　※ 本当は「猫」ではありませんでしたが、猫でマスクしておきます。

# まずは普通に応答

``` nekobot.coffee
module.exports = (robot) ->
    robot.hear /(猫)$/i, (msg) ->
      room = msg.envelope.room
      if room == "image"
        text = msg.match[1]
        msg.send  "#{text} の画像アップするよ"
```

# 画像をアップロード
curlにてアップしたい画像のpathとアップ先のchannelを指定

``` nekobot.coffee
module.exports = (robot) ->
    robot.hear /(猫)$/i, (msg) ->
      room = msg.envelope.room
      if room == "image"
        text = msg.match[1]
        msg.send  "#{text} の画像アップするよ"
        # 下記を追加
        filename = 'image/nya-o.png'
        channel = msg.message.rawMessage.channel
        exec "curl -F file=@#{filename} -F channels=#{channel} -F token=#{process.env.HUBOT_SLACK_TOKEN} https://slack.com/api/files.upload", (err, stdout, stderr) ->
          if err
            # 一応Errorのハンドリングしておく？
```

後は、該当のチャンネルでの `猫` 発言をhubotが拾って指定された猫画像をSlackにアップロード
※画像サイズによってはアップロードに時間がかかります。

# 更に複数の画像をランダムで表示させたい
ということで、表示する画像の配列を作成して、 `random` で取得してみる

``` nekobot.coffee
# 表示したい画像path
neko = ['nya-o.png','bow-wow.png','Cock-a-doodle-doo.png']
module.exports = (robot) ->
    robot.hear /(猫)$/i, (msg) ->
      room = msg.envelope.room
      if room == "image"
        text = msg.match[1]
        msg.send  "#{text} の画像アップするよ"
        # 下記を追加
        filename = msg.random neko
        channel = msg.message.rawMessage.channel
        exec "curl -F file=@#{filename} -F channels=#{channel} -F token=#{process.env.HUBOT_SLACK_TOKEN} https://slack.com/api/files.upload", (err, stdout, stderr) ->
          if err
            # 一応Errorのハンドリングしておく？
```

コレで `猫` に反応したら３種類のどれかの画像がアップします。
※ 連続で同じ画像ばっかりアップされたため、なかなか出なかった画像が当たり扱いされ、いつの間にかくじ引き機能として活躍されるしまつ。。。
Angular2 RC5　Uncaught TypeError: uri.match is not a function に対処する



開発中のAngular2アプリを、RC4からRC5にアップデートしたら、

```
Uncaught TypeError: uri.match is not a function
```

というエラーが表示されて、画面が全く表示されなくなった。

どうやら 

* Webpackを使っている
* 利用しているライブラリのコンポーネントが moduleId を使っている

場合にエラーが発生する模様。

https://github.com/angular/angular/issues/10626

とか

https://github.com/angular/angular/pull/10595

あたりで議論されてて、そのうち修正されると思われますが、今は https://github.com/AngularClass/angular2-seed/commit/84aacc18682bbe38631cd3c457d9e90944d6fd0e に記載されている方法で回避した。

https://www.npmjs.com/package/string-replace-loader を導入して、webpack.config.ts に以下を追記。

```webpack.config.ts

// 省略

module: {
  preLoaders: [
  // 省略
  
  /* FIXME: Angular2 バグ回避 あとで消す */
  {
      test: /.js$/,
      loader: 'string-replace-loader',
      query: {
        search: 'moduleId: module.id,',
        replace: '',
        flags: 'g'
      }
  }
```

js読み込む時に、 ``moduleId: module.id`` という文字列を消してしまう、という方法。

強引だが、なるほど、こんな解決方法もあるのかと関心した。
How to deploy rails5 app on heroku

# Overview
Rails5 アプリを Heroku で公開させるまでのメモ
ローカル環境は docker を利用して port forwarding
docker を利用することによって利用しているホストマシンに
実行環境を用意する必要がない(これが素晴らしい)

# Requirement
* Mac
 * [Docker for Mac OS X](https://docs.docker.com/engine/installation/mac/)
* Windows
 * [Docker for Windows](https://docs.docker.com/engine/installation/windows/)


# How to
https://github.com/sampo02/docker-dev
上記の repository を clone したら使えるようになっています

# Note
## postgres db が起動する前に rails server が起動する
回避策として一度 web を background で起動後に sleep 入れてます(かなり強引なやり方なので他にいいやり方を知りたい・・・)

```bash:startup.sh
docker-compose run -d web
sleep 5
```

## ホストマシンから docker で起動しているアプリに接続
docker 内で起動しているアプリの IP は `0.0.0.0` となるので `rails -b` で
ホストマシンへフォワードできるようにします

```yml:docker-compose.yml
  command: bundle exec rails s -p 3000 -b '0.0.0.0'
```
Spark InspectorがXcode 7.3.1でメニューに表示されない件

#SparkInspectorとは

iOSアプリをデバッグしている時、私にとって必須ツールと言っていいのが、[SparkInspector](http://www.sparkinspector.com/)です。
Spark Inspectorは、iOSアプリのUIをレイヤーごとに分解して、それぞれにどんな値が設定されているのか調べることができます。しかもリアルタイムで！
他人のプログラムをデバッグしたり、ハイブリッドアプリ用のプラグインを開発している時に重宝します。

![Screen Shot 2016-08-20 at 9.58.25 AM.png](https://qiita-image-store.s3.amazonaws.com/0/39529/12665e74-28c2-5ee0-3f15-43997f9a82f1.png)

#Xcode7.3.1との不具合

Spark Inspectorを使うときは、メニューの`[Product] -> [Inspect with Spark]`からアプリを実行します。
ところがXcode 7.3.1にアップグレードしてから、メニューに表示されなくなり、たいへん困っていました。
これを[解決する方法を紹介しているページ](https://www.ikiapps.com/tips/2016/05/04/keep-spark-inspector-available-in-xcode)があったので、要点だけ転載します。

#1. DVTPlugInCompatibilityUUIDの取得

まず`Xcode 7.3.1`のDVTPlugInCompatibilityUUIDというのを取得しなければならないらしいです。
下記のコマンドで取得できます。

```bash
$ defaults read /Applications/Xcode.app/Contents/Info DVTPlugInCompatibilityUUID
```

Xcode 7.3.1のDVTPlugInCompatibilityUUIDは、以下のとおり。
```
ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C
```

#2. Info.plistに追加

このDVTPlugInCompatibilityUUIDをSpark InspectorのInfo.plistに追加します。
Spark Inspectorのプロジェクトファイルを開くには、まずSpark Inspectorを起動して、メニューの`[Window] -> [Getting Started Instructions]`を開きます。

`We’ve copied a plugin into Xcode’s plugins folder`と書いてある横に ">"マークがあるので、それをクリック。
![spark-inspector-getting-started.png](https://qiita-image-store.s3.amazonaws.com/0/39529/3db96a20-4284-c13f-0b7b-64d730275c40.png)

プラグインのある場所がFinderで表示されます。
`SparkInspectorXcodePlugin.xcplugin`を右クリックして、`Show Package Contents`を選択します。
![Screen Shot 2016-08-20 at 10.14.54 AM.png](https://qiita-image-store.s3.amazonaws.com/0/39529/23b76eb3-3426-ad01-10b1-8b34c0a8cbc5.png)

Info.plistファイルがあるので、ダブルクリックでファイルを開き、先ほどのDVTPlugInCompatibilityUUIDを追加して、保存します。
![Screen Shot 2016-08-20 at 10.18.12 AM.png](https://qiita-image-store.s3.amazonaws.com/0/39529/29c548ca-42aa-6ee4-495d-ca3ac2e0e7be.png)

#3. Xcodeを再起動
Xcodeを再起動すると、Xcodeが **Bundleを読み込むかどうか**尋ねるダイアログボックスを表示してきますので、**Load Bundle**を選択します。
<img width="532" alt="load-bundle-view-for-spark-inspector.png" src="https://qiita-image-store.s3.amazonaws.com/0/39529/5c58c7ec-fea8-3749-5f28-ee0084bd5823.png">


そうすれば、メニューに表示されているはず！

![Screen Shot 2016-08-20 at 10.22.25 AM.png](https://qiita-image-store.s3.amazonaws.com/0/39529/bd5f3183-d7e6-69fe-ee84-cb0c83d8ff78.png)
備忘：Linuxでよく使うコマンド


##### 毎回同じことをいろいろなサイトで検索している気がするので備忘録としてよく使うコマンドを記載。
実行環境はまちまちだが、Amazon LinuxもしくはRasbian。
<br>
<br>

### LISTEN状態のポートを調べる
```
$ netstat -nlt

---OUTPUT---

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp6       0      0 :::80                   :::*                    LISTEN     
tcp6       0      0 :::22                   :::*                    LISTEN 

```
-n	ホスト名などを解決せずに数字で表示する
-l	接続待ち状態のソケットのみを表示する
-t TCPソケットを表示する




### 起動中のプロセスを調べる

```
$ ps aux

---OUTPUT---

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  4.4  0.8   5356  3804 ?        Ss   13:55   0:06 /sbin/init
root         2  0.0  0.0      0     0 ?        S    13:55   0:00 [kthreadd]
root         3  0.2  0.0      0     0 ?        S    13:55   0:00 [ksoftirqd/0]
root         4  0.0  0.0      0     0 ?        S    13:55   0:00 [kworker/0:0]
root         5  0.0  0.0      0     0 ?        S<   13:55   0:00 [kworker/0:0H]
root         6  0.1  0.0      0     0 ?        S    13:55   0:00 [kworker/u2:0]
root         7  0.0  0.0      0     0 ?        S    13:55   0:00 [kdevtmpfs]
root         8  0.0  0.0      0     0 ?        S<   13:55   0:00 [netns]

--以下省略--

```

a	すべてのプロセスを表示します。
u	ユーザーフォーマットで表示します。
x	制御端末のないプロセスも表示します。



### コメントアウト以外の行を表示する
```
$　grep -v -e '^\s*#' -e '^\s*$' ファイル名

```
wp-cliでコマンドを打っても動かない場合

wp-cliでdbのインポート／エクスポート及び wp --info は出来るが他のコマンドを入力して

PHP Fatal error:  Call to undefined function apply_filters() in /var/www/wordpress/wp-includes/load.php on line 317

とか言われる。

落ち着こう。PHPのバージョンが多分古い。

~~~
$ wp --info
~~~

などでPHPのバージョンを見てみよう。

古かったら上げる。

vccwの場合は vagrantのあるディレクトリの site.yml に書けばPHPのバージョンを変更できる。
https://firegoby.jp/archives/6211
AWS S3をバックアップの置き場所として使う

(AWS S3を触るのは初めてなので、間違っている点がありましたらご指摘いただけますと助かります！）

さくらVPS（以後、VPS）が高速、かつ、低価格なために愛用している。しかしファイルのバックアップについては悩みがあった。複数台借りているので互いのバックアップをとりあったり特定の1台にバックアップファイルを集約するなどいろいろ方法は考えられる。

今回はAWSの勉強を兼ねてS3をバックアップ場所として利用することにした。

S3のバケットを１つ作り、そこに全VPSのバックアップを入れてもよいが、この場合、VPSの１台がハックされた場合に全サーバのバックアップファイルを取得できてしまう。そこでVPSの1台に対してIAMのユーザを１つ作成、バケットも複数作成して各VPS専用とした。

![s3.png](https://qiita-image-store.s3.amazonaws.com/0/73576/40b1172e-2a4a-267a-0a65-003b463ff555.png)

#### 1. バケットを作成する。最初にバケットを作成する理由は、ポリシーを設定する際にバケットの名称（arn）が必要になるため

![image](https://qiita-image-store.s3.amazonaws.com/0/73576/5841daee-9a4a-08bd-96e1-085e9e2639a9.png)

#### 2. IAMでユーザを作成する（その際、credentialを保存しておく）

![image](https://qiita-image-store.s3.amazonaws.com/0/73576/f77692b9-229a-eddf-2b08-38568ab15133.png)

#### 3. IAMでポリシーを作成する

![image](https://qiita-image-store.s3.amazonaws.com/0/73576/85134c1c-0bfe-cf1f-19fd-ea7ea13dba8e.png)

#### 4. 作成したポリシーをユーザに適用する

![image](https://qiita-image-store.s3.amazonaws.com/0/73576/2fcc643d-48ae-1275-6701-ae8bce2c82be.png)

#### 5. S3に戻り、バケットのパーミッションからバケットポリシーを設定する。私はポリシーエディアを利用した。

![image](https://qiita-image-store.s3.amazonaws.com/0/73576/fa2d7506-1514-ba40-3808-0ba2bba5ceba.png)

Principalの指定だが、IAMの特定ユーザを指定する場合は次のように書く：
```
arn:aws:iam::AWSのアカウントID:user/IAMのユーザ名
```
リソースは次のように書く：
```
arn:aws:s3:::バケット名,arn:aws:s3:::バケット名/*
```

Generate Policyを押し、JSONの中身をコピーして、Bucket Policy Editorにペーストする：

![image](https://qiita-image-store.s3.amazonaws.com/0/73576/5fb0f31b-3f94-158b-fc83-9ec6bb25e92f.png)

#### 6. さくらVPSにログインし、AWSをアクセスするために必要なツールをインストールする

```
yum install python

wget https://s3.amazonaws.com/aws-cli/awscli-bundle.zip

unzip awscli-bundle.zip
cd awscli-bundle
./install -i /usr/local/aws -b /usr/local/bin/aws
```

#### 7. s3のバケットが見れるか、確認する

```
aws s3 ls s3://bucket-for-sakura-vps1
```
（エラーが出なければOK）

#### 8. s3にファイルをアップロードしてみる

```
touch hoge
aws s3 cp hoge s3://bucket-for-sakura-vps1
```

```
upload: ./hoge to s3://bucket-for-sakura-vps1/hoge
```
と出力されればOK。
[Unity]ADX2 LEを使ったときに実機で音が出ないときのメモ

ADX2 LEを使ったときに、PC上ではちゃんと音が鳴るのに、実機(Android)では音が鳴らないときの原因の1つとしてのメモ。

#実行環境
・Windows 10
・Unity 5.4.0f3
・音関係はADX2 LEを使用
・実機はAndroid 5.1.1

#原因はVoicePoolを増やしすぎた
PC上では音が出ているため、Android向け機能の問題であると推測した。
今のところAndroid向けの機能としては、音の遅延をなくすために、ADX2 LEのLow Latency機能のみを実装している。
その設定がおかしいのではないかと考えた。

その数は*CriWareLibraryInitializer*で設定することができるが、

[サウンド助け合い所　ADX2LE情報](https://www53.atwiki.jp/soundtasukeai/pages/22.html#id_ecee8fa6)

によると、
**低遅延再生標準ボイスプールの最大数はメモリ再生・ストリーム再生あわせて27まで。**
ということが注意点。

勝手に32までだと勘違いしていたのが今回の原因だった。

実機で動作しないと焦るね・・・
Sphinxをバージョンアップする


ローカルにインストールしてあったSphinxが古かったのでアップデートしてみた。

## 手順
### インストール前のバージョン確認

```
% pip show sphinx                                                             
---
Name: Sphinx
Version: 1.2.3
Location: /Library/Python/2.7/site-packages/Sphinx-1.2.3-py2.7.egg
Requires: Pygments, docutils, Jinja2
```

### アップデート
```
% sudo pip install sphinx --upgrade --ignore-installed six
```

### アップデート後のバージョン確認
```
% pip show sphinx
---
Name: Sphinx
Version: 1.4.6
Location: /Library/Python/2.7/site-packages
Requires: babel, Jinja2, alabaster, imagesize, six, Pygments, snowballstemmer, docutils
```
MacにGo言語をインストール。Hello Worldまで。


OSのバージョンは10.11.5。

### Go言語をインストール
[こちら](https://golang.org/dl/)のリンクから最新版のURLを取得してください。  
今回使用するGo言語のバージョンは1.7。  
パッケージのダウンロードが終わったらダブルクリックして、指示にしたがってインストールを完了させてください。

下記のコマンドでGo言語がインストールできているか確認

```
$ which go                                                                     
/usr/local/go/bin/go
```

### Go言語の初期設定
ワークスペースと呼ばれるディレクトリを作成して、GoPATHを設定します。

今回のワークスペースは **$HOME/dev/work** にします

```
mkdir -p ~/dev/work
```

GoPATHを設定します。
普段使っているシェルがzshなので以下のようにします。

```
$export GOPATH=$HOME/dev/work > ~/.zshrc
source ~/.zshrc
```

次にワークスペース内にhello worldのプログラムを配置させるためのディレクトリを作成します。
私のGitHubのユーザー名が **YuzuruS** なので以下のようにします。

```
mkdir -p ~/dev/work/src/github.com/YuzuruS/hello
```

これで準備は完了です。

### Go言語でHello World

```~/dev/work/src/github.com/YuzuruS/hello/hello.go
package main

import "fmt"

func main() {
    fmt.Printf("hello, world\n")
}
```

セーブしたらコンパイルします。

```
$ go install github.com/YuzuruS/hello
```

するとワークスペース内のbinディレクトリ以下にhelloという実行ファイルが出来上がっているので、実行してみます。

```
$ $GOPATH/bin/hello
hello, world
```

以上です。
bashオプション-uを付けた状態での未定義変数チェック方法


bashを利用する場合には、オプション-uを必須にしている人も多いと思います。
たまに、変数が未定義であるかどうかを確認する処理を書きたくなることがある。
一時的にオプション-uをOFFにするなど、方法はいろいろありますが、testコマンドで実現したかった。

結論から言うと、testコマンドのオプション-vで実現できた。

>        -v varname
>              シェル変数 varname がセットされている (値が代入されている) ならば真となります。


```bash:unset_var_check_sample1.sh
#!/bin/bash -u

# -vオプションを利用した未定義確認
if [ -v VAR ];then
  echo "Y" # VAR変数は定義済み
else
  echo "N" # VAR変数は未定義
fi

VAR="value"

# -vオプションを利用した未定義確認
if [ -v VAR ];then
  echo "Y" # VAR変数は定義済み
else
  echo "N" # VAR変数は未定義
fi
```

ただ、bashのバージョン次第ではtestオプション-vをサポートしていないこともある。
testオプション-zあたりを使えば、未定義もしくはから文字列の判定ができるが、bashオプション-uを定義しているとそれができない。
そのため、パラメータの展開を利用して実現してみた。

> パラメータの展開
> 
> (中略)
>
> 部分文字列展開以外の場合、以下の形式で、        bash        はパラメータが設定されているか、空ではないかを調べます。
> コロンを省略した場合には設定されているかどうかのみを調べます。
> 
> ${parameter:-word}
> 　　デフォルトの値を使います。
> 　　parameterが設定されていないか空文字列であれば、wordを展開したものに置換されます。
> 　　そうでなければ、 parameter の値に置換されます。

パラメータ展開は使ってはいたもののmanで調べたことがなかったため、見てみるとなかなか面白い。
` "${VAR-UNDEF}" = "UNDEF" `で済ませるケースも見ますが、それでは実際にUNSETが代入されていた場合と違いが付かない。
そこで、2回別変数でチェックすれば未定義確認は可能になる。
＃ ただスマートさに欠ける。。。

```bash:unset_var_check_sample2.sh
#!/bin/bash -u

# パラメータ展開を利用の未定義確認
if [ "${VAR-A}" = "A" ] && [ "${VAR-B}" = "B" ];then
  echo "N" # VAR変数は未定義
else
  echo "Y" # VAR変数は定義済み
fi

VAR="value"

# パラメータ展開を利用の未定義確認
if [ "${VAR-A}" = "A" ] && [ "${VAR-B}" = "B" ];then
  echo "N" # VAR変数は未定義
else
  echo "Y" # VAR変数は定義済み
fi
```

ちゃんと調べてみると、以下のパラメータ展開があった。

> ${parameter:+word}
> 　　別の値を使用します。  parameter が空文字列または設定されていなければ、空文字列に置換されます。 そうでなければ
> 　　word を展開したものに置換されます。

つまりは、変数が空文字列、もしくは未定義ならば空文字列を、それ以外ならばwordを展開してくれるというもの。
オプション-zで返ってくる値が空文字列かをチェックすれば良い。
うん、スマートになりました。

```bash:unset_var_check_sample3.sh
#!/bin/bash -u

# パラメータ展開を利用の未定義確認
if [ -z "${VAR+UNDEF}" ];then
  echo "N" # VAR変数は未定義
else
  echo "Y" # VAR変数は定義済み
fi

VAR="value"

# パラメータ展開を利用の未定義確認
if [ -z "${VAR+UNDEF}" ];then
  echo "N" # VAR変数は未定義
else
  echo "Y" # VAR変数は定義済み
fi
```
ハッシュを用いたブラウザバック問題の対応策

ネットで調べるとだいたい以下の様な対応策をよく目にする。

* `onunload`や`onpageshow`イベントで何かしらの制御
* ブラウザバック時に画面リロード
* （そもそもキャッシュさせない、というのもあった）

これらでもできるのであろうが、今回は別の方法としてURLにハッシュを付ける方法のメモ。個人的にはこっちの方が分かりやすく、かつ使う場面がイメージしやすくて気に入ってる。（以下の例ではログアウト後のブラウザバックの対応）


# 対応策のコード
まずは画面遷移するためのボタンやリンクに`hoge`というid属性を付与。

```html:ボタンの例
<!-- form内のボタン -->
<form method="post" action="/logout">
  <button type="button" id="hoge">logout</button>
</form>


<!-- 単にリンクが貼ってあるボタン -->
<a href="/logout" id="hoge">
  <input type="button" id="hoge" value="logout">
</a>

<!-- そもそもリンクにハッシュを付けても良い -->
<a href="/logout#logout">
  <input type="button" id="hoge" value="logout">
</a>
```

上記のボタンに`click`イベントリスナーを付与し、コールバック関数の中で`#logout`というハッシュを付与。上記の3つ目の例のようにハッシュをつけたリンクを貼ってもいいが、これは使いどころが限定されるので汎用性は低いかと。

```js:素のJavaScript
// submitやリンクによる画面遷移前に実行
var target = document.getElementById('hoge');

target.addEventListener('click', function() {
   window.location.hash = '#logout';
});
```
```js:jQuery
$('#hoge').on('click', function() {
   window.location.hash = '#logout';
});

// ※他のイベントリスナーによりうまく動かない場合はこう
$(document).on('click', '#hoge', function() {
   window.location.hash = '#logout';
});
```

最後に、画面アクセス時に`#logout`というハッシュがあるかを確認し、あればブラウザバックをした時の画面に戻すか、任意の画面にリダイレクトする。

```js

(function() {
   if (location.hash === '#logout') {
      // 画面を戻す
      history.forward();

      // リダイレクト
      location.href = '/path_to_any_page/';
   }
}());
```

# 簡単な説明
流れを簡単に説明するとこう。

1. `JavaScript`でURLの末尾に指定のハッシュがあるか検知
2. あり:リダイレクトして終了
3. なし：任意のリンク or ボタンに`click`やなどのイベントを付与
4. イベントが付与されたリンク or ボタンからイベントを発火
5. 現在のURLの末尾に指定のハッシュを付与し画面遷移、または`submit`
6. 遷移先の画面からブラウザバックを実行
7. 1に戻り、2で終了


# 余談
そもそも遷移先のURLにハッシュをつければ、jsでハッシュを付与する処理は不要なのだが、実際の現場では意外とハッシュが目に見えるのを嫌うお客さんが多いので、見えない形にするならこのやり方になるかなと。

あとは以下のように、

```html

<form name="form_logout" method="post" action="/logout">
  <input type="button" id="hoge" value="logout">
</form>
```

```js

var target = document.getElementById('hoge');

target.addEventListener('click', function() {
   window.location.hash = '#logout';
   document.form_logout.submit();
});

```

`button`タグじゃなく`input`タグのボタンを設置し、submitもjsで制御するやり方もあるが、ちょっと古いかな。まぁ、他にもいろんなやり方があるのでこういうやり方もあるよ、といったとこ。
pyenvで入れた複数バージョンに対してdjangoをインストールした時のメモ


## pyenvのバージョンがデフォルトで2.7.9の時

```
$ which python
~/.pyenv/shims/python
$ python -V
2.7.9
```

これがデフォルトになっている時に、自分の作業ディレクトリがpyenvでpython3.4.3のバージョンを設定している時にそのまま

```
django-admin,py startproject [project-name]
```

とした時に

```
No import module django.core
```

のようなエラーが出る。
このような時は.pyenv以下のディレクトリに入っているdjango-admin.pyのあるディレクトリのpyenvのバージョンが2.7.9になっていることが多い。
そのため、そのディレクトリに移動して、

```
pyenv local [今回の作業バージョン]
```

とすることで、今回のバージョン下で実行できるようになるので、エラーが消える。
pipでPILインストール

pipでPIL（Python Imaging Library）をインストールしたときにハマったのでメモ。

# インストール時の環境
MacOS X El Capitan（バージョン 10.11.6） 
Python 2.7.10
pip 8.1.2

# ダメだった。
`$ sudo pip install pil`

# インストールできた。
`$ sudo pip install pillow`
Windowsで実行ファイルのアクセスエラーが偶発するやつ

技術系の話題なのかどうか微妙だけども、実際コンパイル中に起きて詰まったのでここに。

状況
===
実行ファイル(*.exe)がたまに、権限なくて実行失敗する。いわゆるpermissiopn denied。実行ファイルや上位フォルダのセキュリティ設定をいじっても効果なし。常時失敗するわけではなく、再度実行すると大抵成功する。

どうやらコマンドラインツールばかり引っかかる模様…。うちで引っかかったのは、自作動画エンコードバッチのffmpegとか、Visual Studioでクロスコンパイルするときのclang.exeとか。

原因
===
アンチウィルスソフト Avast! の ファイルシステムシールド。
とりあえず必要なときは一時的にオフにする運用で…


環境
===
Windows7 (64bit)
Avastは2016年6月頃のバージョン。
Swift3.0でのstringByTrimmingCharactersInSetの変更点


string.stringByTrimmingCharactersInSetがSwift3.0で使えなくなってます。

Swift2.0

```
var cString:String = hex.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()).uppercaseString
```

Swift3.0

```
var cString = hex.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).uppercased()
```
 
Swift3.0では

```
trimmingCharacters
```
に変わっています。
【Cordova】小さい斜め気味のスワイプでも反応する simple_swipe.js

##使えるシーン
- 「親指による小さめの上下のスワイプ」を取得したい
- ななめにスワイプしても反応させたい

既存のスワイプ系ライブラリは高機能で使いやすいものが多く存在しますが、上記の条件を満たすものが（私の調査では）見つからなかったので作りました。jQueryプラグインなので、ハイブリッドアプリ（Cordova）じゃなくても使えます。

##simple_swipe.js ( jQuery依存 )
###概要
- 上下左右のスワイプに応じて、「swipe_up , swipe_down , swipe_left , swipe_right」という jQuery Event を発生させます。 

###ダウンロード
https://github.com/YusukeSakurai/simple_swipe.js

###インストール
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script type="text/javascript" src="simple_swipe.js"></script>

通常のjQueryプラグインと同様に、jQuery本体を読み込んだ後に simple_swipe.js を読み込みます。

###使い方
<pre>
$(/*selector*/).on("swipe_up", function(){
    /*Function*/
});
</pre>
通常のjQueryイベントと同様に使えます。

###まとめ
（あまり使う場面はないと思いますが）「小さめの斜めスワイプ」でも反応するので、操作感は良好です。
launchd で起動している Jenkins 内で xcodebuild がコケた話。

iOS アプリのビルドから ad hoc 公開まで自動化しようとした過程で躓いたので、
備忘録を兼ねてここに記します。

#要約
xcodebuild のパラメタの
CODE_SIGN_IDENTITY は "iPhone Distribution: XXXXXX XXXXXX (XXXXXXXXXX)" を
PROVISIONING_PROFILE はすべて小文字で表記された UUID を正確にコピペしていることを確認したうえで、
launchctl に読み込ませている plist に以下のプロパティを設定する。

- UserName : iPhone Distribution の証明書をインストールしたユーザーのアカウント名 (not 表示名)
- GroupName : UserName で指定したユーザーが所属するグループ名 (基本的には staff だと思う。)
- SessionCreate : true にする。 (公式のドキュメントは見つからなかったが、どうも環境設定やデフォルト参照する keychain の初期化を行うかのフラグらしい。)

もう少し具体的に plist の中身を示すとこんな感じ。

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
	<dict>
		<key>Label</key>
		<string>(サービスを区別するために使用する識別子)</string>
		<key>UserName</key>
		<string>hogehoge</string>
		<key>GroupName</key>
		<string>staff</string>
		<key>SessionCreate</key>
		<true/>
		<key>ProgramArguments</key>
		<array>
			<string>/path/to/start_jenkins.sh</string>
		</array>
	</dict>
</plist>
```

(追記)
上記の設定をした上で /path/to/start_jenkins.sh にて jenkins を起動する直前に
`security unlock-keychain -p <password>` を実行する必要がありました。

#経緯
当初、とりあえず El Capitan な macbook air 1 台に nginx をフロントに立たせて jenkins を jar から起動して環境構築を行っていました。
いろいろと試行錯誤しながらもとりあえずビルドが通る様になったので、
jenkins も jar を直接立ち上げるのではなく、
launchd で起動時に勝手に立ち上がるように (root 直下の) /Library/LaunchDaemons/ に plist を追加して、いざ `launchctl load` をしてみた。
…起動はうまく行った。

しかし、この修正を行った途端に xcodebuild の終盤、署名を行うタイミングでコケるように。
先ほどはビルドは通ったとは言え、間違えていじってしまったかと思い xcodebuild に渡していたパラメータをチェックするも、
CODE_SIGN_IDENTITY や PROVISIONING_PROFILE に指定ミスは無かったので、
いろいろと原因を探っていましたが、
ふと前に手動で mac の端末移行のためのバックアップをした時に ~/Library/Keychains/login.keychain ファイルをコピーしたことを思い出し、
おもむろに jenkins のタスク内で `security list-keychains` をしてみた。
すると

```
+ security list-keychains
    "/Library/Keychains/System.keychain"
    "/Library/Keychains/System.keychain"
```

と、証明書の鍵が入っているであろう ~/Library/Keychains/login.keychain は読み込まれていないことが発覚。

そこでこれを頼りにいろいろ調べてみると、`security default-keychain` と `security unlock-keychain` コマンドを jenkins の起動直前に叩くようにする方法が見つかるも、
unlock-keychain するためには平文でパスワードをパラメタとして渡さなければいけないので、なるべく避けたい。

より検索の深みに嵌っていったところで、SessionCreate の情報を掴み試してみたところこれがビンゴ。
その結果、上の要約に書いた設定に落ち着きました。
めでたしめでたし。 (だといいなぁ…。)

(追記)
結局、`security unlock-keychain -p <password>` を jenkins を起動する直前に実行しないと署名が正しく完了しませんでした。
bashで文字列を変数名に展開する方法


文字列を変数名として利用したいことがある。
evalを利用すれば簡単に実現できた。

以下のサンプルでは、var_nameという文字列をそのまま変数名に利用する。

```bash:eval_sample1.sh
#!/bin/bash -ue

# 変数strにvar_name文字列を格納
str="var_name"
# evalを利用してvar_nameに"value"
eval $str="value"
# var_nameを表示
echo $var_name
```

また、変数に利用したい変数名を入れるようなスクリプトを作りたいことも多々ある。
この場合もevalを利用して一度文字列を展開すれば実行できる。
以下のサンプルではecho実行時に文字列を変数に展開した。

```bash:eval_sample2.sh
#!/bin/bash -ue

# 変数var_nameを定義
var_name="value"
# 変数strにvar_name文字列を格納
str="var_name"
# var_nameを表示
eval echo '$'$str
```
Webプログラマ向けハードウェア自動設計ツールmille-feuille（ミルフィーユ）～ハードの仕組み編


#ミルフィーユ基板（mille-feuille board）とは
ミルフィーユ基板の使用方法概要はこちら→http://qiita.com/my_mil_info/items/ac484c96c867c1b3e702

ソフトの書き方も、間もなく公開します！

ここではハードの仕組みを説明します。基本的にミルフィーユはデジタルスイッチ群を介して自動配線をしながら動いています。Raspberry Pi・ブレッドボード・デバイス間を手で配線していた作業を、この仕組みが手の代わりに自動で行うことによって試作開発の時間を短縮できます。
デバイスボードは理論上、電力が届く限り積層可能ですが、最大数4列×5段を想定して設計されています。

##ミルフィーユ基板の構成
ミルフィーユはRaspberry Pi、ベースボード、モジュール、フラットケーブル、デバイスボードで構成されています。（国内外で特許取得済みですが、デバイスボード部分はオープンハードです。）

![HardAll.jpg](https://qiita-image-store.s3.amazonaws.com/0/96369/7e302373-79e0-34bd-a2f5-e83d3006b203.jpeg)


###Raspberry Pi
Raspberry Pi A+、B+、2、Zero、3が使用可能です。
B+と同じIO端子ならどれでも使用できますので、今後も新しいRaspberry Piが発売された場合は、B+と同じIO端子であるかを確認してみてください。

Raspberry Piだけではなく、CortexM3やM4版も開発予定です。

自動配線機能は、3線SPI 17MHz 信号で行っています。
(旧MCU GearはI2C 1MHzでしたが、ミルフィーユではより高速なSPI 17MHzに変更しました)

###ベースボード（Baseboard）
ベースボートには2つのチップが搭載されています。

1、デジタルスイッチ群
配線のためのマルチプレクサに似たデジタルスイッチ群があらかじめ書き込まれたFPGA

2、ARM Cortex-M0
デジタルスイッチの動作を補うサブコントローラー
レジスタや通信など比較的面倒な処理を管理しています

ベースボードではFPGAのチップを使用していますが、ユーザーがFPGAそのものをverilog HDLなどで書き換えるわけではありません。
ユーザーが「このデバイスに接続して！」と命令プログラムをライブラリから実行すると、ユーザーの見えないところでFPGAにあらかじめ書き込まれているマルチプレクサが、命令されたデバイスを接続するよう切り替わるという仕組みです。
ミルフィーユはプログラマ向けのデバイスのため、ユーザーが高度なFPGAを駆使して論理回路を再合成する仕組みではありません。
一度デジタルスイッチで配線が終わった後は、デバイスを手で配線したような状態で動かすことができます。

###モジュールボード（Module board）

モジュールボードの役割はベースボード・デバイスボード間の接続制御です。
6層基板にARM Cortex-M0を搭載し、バススイッチをコントロールしています。6層基板でもギリギリの配線です。

1、アドレスの一体化
モジュールボードにデバイスボードを接続すると、自動的にデバイスボードに搭載されているEEPROMからアドレスを読み取り、何のデバイスが接続されたかを認識します。
その際にモジュールボード自体にもデバイスボードと同じアドレスが割り振られます。そうすることでモジュールボードとデバイスボードが一体化・一つのボードとなり、ユーザーからの命令をコントロールできます。
モジュールボードはデバイスボードに繋げてから自分自身のアドレスが割り振られるため、デバイスボード毎にモジュールボードを付け替える必要がなく、どのデバイスボードにも対応できます。


2、信号の保持機能
デバイスボードへの接続終えた際、使用していないデバイスボードのゲートが閉じてしまうため信号がハイインピーダンスになり、その信号がHighかLowか分からなくなってしまします。この信号保持機能は、ゲートが閉じる直前のHighなのかLowなのかの信号を読み取り保持する役割を担っています。
この機能はライブラリ内で自動制御されています。

3、通信遅延
デバイスボードとの通信において、以下の通信遅延が生じます。
・SPI通信：約2nsec
・GPIO通信：約25nsec
・I2C通信：直結

4、独立した電源回路
モジュールボードには3.3Vの独立した電源回路が搭載されており、1つのモジュールボードに対して最大300mAが流せます。

![hard.png](https://qiita-image-store.s3.amazonaws.com/0/96369/1d32b71f-659a-214c-6bbe-bddc49b30660.png)
図はRaspberry PiのGPIOを自動配線した際のデジタル端子の詳細です。
・PIN1～4はマルチプレクサやバススイッチを介したGPIO
・SCL、SDAはI2C

###デバイスボード（Device board）

ミルフィーユのデバイスボードには、ブレークアウト基板などにフレキシブルケーブルのコネクタ、デバイスアドレス用のEEPROMが搭載されたものになります。
このEEPROMや基板の配線方法がモジュールボードと連動し、pythonライブラリ、Web上の回路図自動生成ツール、ファームウェア自動変換ツールを操作することが可能です。

・オープンハード（2017年開始予定）
ベースボード、モジュールボードはオープンハードではありませんが、デバイスボードはオープンハードです。また、ユーザーがミルフィーユ対応のデバイスボードを開発し販売することも可能です。
ミルフィーユのデバイスボードには個々にアドレスが設定されています。
ユーザーが開発したデバイスボードにもアドレスを発行し、ミルフィーユ対応のデバイスボードとして別のユーザーにも使ってもらうことができます。
オリジナルのデバイスボードを開発し、モノづくりをもっと楽しみましょう。
![hard2.png](https://qiita-image-store.s3.amazonaws.com/0/96369/384609a1-c6ef-f199-e5f8-7f2f803d2263.png)

###おまけ：UART(serial)バス
UART(serial)バスはベースボード横のフレキシブルケーブルコネクタを使用します。基本的には1対1で動作させることを目的としており固定された配線です。

![hard3.png](https://qiita-image-store.s3.amazonaws.com/0/96369/a584488b-df68-e3b7-1bc6-d294b2fe0dcd.png)
図はRaspberry PiのGPIOを自動配線した際のデジタル端子の詳細です。
・PIN1,2はマルチプレクサを介したGPIO
なぜJava8のStreamAPIのmapのシグネチャはmap(Function<? super T,? extends R> mapper)なのか？

なぜJava8のStreamAPIのmapのシグネチャはmap(Function\<T,R\>mapper)ではなくmap(Function\<? super T,? extends R\>mapper)なのでしょうか。
またそうだとしても、PECSでは入力となるオブジェクトのコンテナをColection<? extends T>として、出力をCollection<? super R>に格納するのでしたが、Stream APIの各メソッドに渡す関数の入力パラメータは?super Tになっており、出力が? extends Rになっています。PECSとは逆になっているような気がします。
# 具体的な型
例えばmapは
map(Function<? super T,? extends R> mapper)
forEachは
forEach(Consumer<? super T> action)
のようにワイルドカードが指定されています。
具体的なイメージを湧かせるために、Animalとその派生クラスで考えます。

```java:class
class Animal(){
}
class Dog extends Animal(){
}
class Puppy extends Dog(){
}
class Cat extends Animal(){
}
class Kitty extends Cat(){
}
```
DogはAnimalのサブクラスとします PuppyはDogのサブクラスとします
CatはAnimalのサブクラスとします KittyはCatのサブクラスとします
# シグネチャの解釈
map(Function\<? super Dog,? extends Cat\> mapper)
の解釈は
（誤）mapは、Dogの先祖を入力できてCatの子孫を出力する　ではなく
（正）mapはDogを入力してCatを出力するのだが、mapに渡すmapper関数は、Dogの先祖を入力できてCatの子孫を出力するものであれば良い
と考えられます。
入力と出力の型が異なるいろいろな種類のmapper関数があるものとします。
すべての組み合わせを羅列すると冗長なので、入力だけをDogでないものにした組み合わせ、出力だけをCatでないものにした組み合わせ、および最後に入力も出力もDog,Catでないものの例を表にしてmapに渡せるかどうかを見てみます。

| 入力型| 出力型 | mapメソッドに渡せるのか？ |
|:-:|:-:|:-:|
|Dog|Cat|OK|
|Animal|Cat|OK|
|Puppy|Cat|NG|
|Dog|Animal|NG|
|Dog|Kitty|OK|
|Animal|Kitty|OK|
map(Function\<T,R\>mapper)であればmapには一番上の入出力を取る関数しか渡せませんが、map(Function<? super T,? extends R> mapper)となっているので、表のOKの関数ならmapに渡せます。
例として表の一番下のFunction\<Animal,Kitty\>型関数をmapに渡してみます

```java:例
void test(){
    //入力のList<Dog>を準備
    List<Dog>l=new ArrayList<>();
    l.add(new Dog());
    //Function<Animal,Kitty>型の関数を作る
    Function<? super Dog,? extends Cat> mapper=new Function<Animal,Kitty>(){
      public Kitty apply(Animal a){ 
        Kitty k=new Kitty();
        k.name=a.name;
        return k;
      }   
    };  
    
    l.stream()
      .map(mapper) //Function<Dog,Cat>ではなくFunction<Animal,Kitty>型を渡す
      .forEach(p->p.mew());//pはCat型
  }
```
mapメソッドとしてはDogを入力としてCatを出力しますが、mapperはAnimalを入力としてKittyを出力しています。これは、表中のOKのシグニチャの関数をmapperに取る限り、mapメソッド内では
map入力のDog-->アップキャスト-->mapper入力Kitty-->mapper処理-->Kitty出力-->アップキャスト-->map出力Cat
のようにアップキャストしか行われず型安全であることが保証されます。
 
実際にはDog入力Cat出力以外の関数を実装した匿名クラスを渡すことは稀で、ラムダ式を書くことが普通で、mapのシグネチャがmap(Function\<T,R\>mapper)となっていると思っていても何ら実用上問題はないのですが、改めてマニュアルを見てアレレとなってしまわないように。