OmniAICreator/Qiita-1.07M huggingface dataset:
railsでの、文字コード変換で発生する特定文字列の例外対処

CSVダウンロードの実行でUTF-8からsjis変換時に例外が発生。

いわゆる[波ダッシュ問題](http://x0213.org/wiki/wiki.cgi?page=%C7%C8%A5%C0%A5%C3%A5%B7%A5%E5%CC%E4%C2%EA)の対応方法備忘録。


## 環境
```
$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin15]

$ rails -v
Rails 5.0.0.1
```

## helperを実装

application_helper に変換用のメソッドを追加。

```ruby:app/helpers/application_helper.rb
module ApplicationHelper
  # 文字コード変換用のリスト
  FROM_CHR_UTF8 = "\u{301C 2212 00A2 00A3 00AC 2013 2014 2016 203E 00A0 00F8 203A}".freeze
  # 〜−¢£¬–—‖‾ ø›
  TO_CHR_SJIS   = "\u{FF5E FF0D FFE0 FFE1 FFE2 FF0D 2015 2225 FFE3 0020 03A6 3009}".freeze
  # ～－￠￡￢－―∥￣ Φ〉

  # UTF-8をSJIS変換時に、変換できない文字を変換できる文字に置換する。
  def sjisable(str)
    return if str.blank?
    str.tr!(FROM_CHR_UTF8, TO_CHR_SJIS)

    # 指定した文字から漏れた変換できない文字は、「?」に置換する。
    str.encode(Encoding::SJIS, Encoding::UTF_8, invalid: :replace, undef: :replace).encode(Encoding::UTF_8, Encoding::SJIS)
  end
end
```

## 使用

```ruby

sjisable(string)
```

## 確認
```ruby
str = '〜−¢£¬–—‖‾ ø›'
p str
p sjisable(str)
# => 〜−¢£¬–—‖‾ ø›
# => ～－￠￡￢－―∥￣ Φ〉

p sjisable('ä啟')
# => ??
```

## 追伸

- 文字列を渡すのではなく、配列をまるっとわたせるメソッドの方が、CSVを扱うには有用で、カラム追加時等でもバグ生みにくいか。
- 変換のセットをhashで持つほうが保守性高そう。

## 参考

- [Windows\-31Jに変換する時の例外を防止するためのString拡張 \- Qiita](https://qiita.com/yugo-yamamoto/items/0c12488447cb8c2fc018)
- [String\#encodeが変換できそうで変換できない文字 \- ネットの海の片隅で](http://osa.hatenablog.com/entry/2014/08/21/113602)
- [encode, encode\! \(String\) \- Rubyリファレンス](https://ref.xaio.jp/ruby/classes/string/encode)
- [tr, tr\! \(String\) \- Rubyリファレンス](https://ref.xaio.jp/ruby/classes/string/tr)
PhpStorm の throws のチェックがうるさい

PhpStorm は、呼び出したメソッドの phpdoc の `@throws` をヒントに try-catch の不足などをインスペクションすることができます。が、これが現状の PHP コミュニティの例外の意味付けのブレ (PHPの例外はすべて非検査例外 v.s. RuntimeException以外は検査例外) に合わなくて、いろいろなライブラリを使うとすぐに黄色くなってしまいます。

また、「すべての Throwable 発生に割り込んで何かしておきたい」というような場合も、

```php
catch (\Throwable $e) {
    // なにかやる
    throw $e;
}
```

とすると、メソッドの doc コメントに `@throws` が足りないよという警告が出て、それに従ってしまうとこんど、コール側に Throws の catch が必要だよという、わけのわからない警告になってしまいます。

そんなこんなでインスペクションを切ってしまうと、こんどは、ビジネスロジック上の例外を捕捉必須のつもりで投げてるところで、捕捉漏れが起きることに...

というわけで、ひとまず大真面目に例外のハンドリングをどう書けばいいか考えました。

PHP >= 7.1 です。

```php
/**
 * @throws RecoverbleDbException
 */
function doSometiong()
{
    $db->beginTransaction(); // RecoverbleDbException が起きるかもしれない

    try {

        // ...

    } catch (DuplicatedOperationException $e) {  // ... 1
        // 自己解決できる例外は中でしれっと処理
        $db->rollback();
        return;
    } catch (RecoverbleDbException $e) {  // ... 2
        $db->rollback();
        // 検査例外はコール側にキャッチさせるべき例外なのでそのまま投げて @throws に明記。
        throw $e;
    } catch (\RuntimeException | \LogicException | \Error $e) {  // ... 3
        $db->rollback();
        // 非検査例外は想定外で予測不能、もれなくキャッチさせるのは不可能なので
        // @throws に書かれている必要はない。
        throw $e;
    } catch (\Exception | \Throwable $e) {  // ... 4
        $db->rollback();
        // もしここに漏れてくるなら、それは検査例外の捕捉漏れか、現在の PHP
        // にない第三の Throwable ということになる。
        // 検査例外が漏れてくるということは実装に捕捉漏れがある証拠、あるいは
        // 仕様をフォローできていない PHP メジャーバージョンに上げたということ。
        // どちらも、LogicException で実装ミスを報告する。
        throw new \LogicException("Unhandled Exception or Throwable:" . get_class($e), 0, $e);
    }
}
```

1. 既知の例外のうち自己解決するもの
2. 既知の検査例外を呼び出し側に任せたい場合
3. 非検査例外
4. 未知の検査例外の検出

1 と 2 は問題ないですね。2 の方だけが `@throws` に登場し、こいつは呼び出し側に処理する責任がある。`@throws` にあるのは「呼び出ロジックが絶対にキャッチしなければならない例外」です。API インターフェース仕様の一部って扱いですね。

3 は非検査例外です。これは `throw $e` やっていても phpdoc には何も書かないのが普通です。PhpStorm は書いても無視します。2 と 3 は PHP 7.1 なら `|` で合体させてもいいですね。

さて問題は 4 です。「既知の検査例外」と「すべての非検査例外」をキャッチしたあと、漏れてくる Exception とは何でしょう? そうですね、あってはいけないはずのフローです。検査例外は `@throws` によって呼び出し側に何らかのハンドリングが必須だとしているのですから、思ってもいない例外が漏れてくるはずがありません。なので、プログラムが正常なら起きないはずの LogicException に例外を翻訳するべきです。(PHP に UnexpectedExceptionException みたいなのがあれば良かったんですが、適当なのがないので)

... でも

これ、コンパイラが絶対にリリースを許さないとかなけでば、こういう連鎖って実質無理じゃね? というのが現実でして...えぇ

正直めんどくさい。めんどくさいものは流行らない。

というわけで、PhpStorm のインスペクション機能をオフにせずに、都合よく警告を抑制したいというレベルまで意識を下げると、人知れずこっそりこういう...

```php
/**
 * @throws RecoverbleDbException
 */
function doSometiong()
{
    try {

        // ...

    } catch (RecoverbleDbException | \Throwable $e) {
        $db->rollback();
        (function () use ($e) { throw $e; })();
    }
}
```

クロージャーは静的な呼び出し階層解析に含まれないので、これで一応黄色いのはなくなります。throw が発生するフローが静的に辿れなくても、べつに `@thorws` に「出るからね」というインターフェースを宣言するのは間違いじゃないですし。

ま、PhpStorm があとちょっとこうなったらな、なんですよ。例外捕捉をチェックしないクラスの設定、こういうふうにカスタマイズできるようになったらなとずっと思っているんだけど、2018.1 でもだめでした。

- Error 型とその派生クラス
- LogicException 型とその派生クラス
- RuntimeException 型とその派生クラス
- Throwable 型 (実装を含まない) ← これと
- Exception 型 (派生クラスを含まない) ← これ追加

まあダメですね... もし Exception で捕まえて throw したら、握りつぶしたかに見えながら、実際は何が出てくるかわからない怖いメソッドになりますね。うーん... まあもともと PHP がそういう世界観だからねといえばそうかもしれないけど。

結論はありません。PSRがんばれ
UbuntuをThinkPadに入れたらWi-Fiが繋がらなかった話

# はじめに

- 機種：ThinkPad E480
- 環境：Ubuntu16.04LTS　

# USBからBootしてUbuntuをインストールする
[こちらのサイト](https://yoshinorin.net/2017/04/29/remove-windows-and-install-ubuntu-from-usb/)を参考にインストールした。
LTSのバージョンのほうが安定してるということからUbuntu16.04LTSをインストールした

# どれだけ頑張ってもWi-Fiが繋がらない
ターミナルを立ち上げ確認してみる。

```bash:lspci
$ lspci -nnk | grep 0280 -A3

05:00.0 Network controller [0280]: Realtek Semiconductor Co., Ltd. Device [10ec:c821]
    Subsystem: Lenovo Device [17aa:c024]
```

一応Network controllerは入っていてWi-Fiは使えるらしい。
Windows10を入れてた時にはWi-Fiが使えてたのだからそれはそうだ。
[調べてみると](https://askubuntu.com/questions/990378/wifi-not-working-on-lenovo-thinkpad-e570)ThinkPadに使われているWi-Fiのネットワークカード*RTL8821CE*がLinuxに対応していないらしい。
上記のリンクの方法でWi-Fiが使えるようになったという人が何人がいたが、自分が試してもダメだった。
[Ukuuでカーネルをアップデート](https://fossbytes.com/install-upgrade-linux-kernel-ubuntu-mint-ukuu/)すれば上記のリンクの方法でいけた。

#解決方法
##カーネルのバージョン確認
まずはカーネルのバージョンを確認する。

```bash:uname
$ uname -a
```

カーネルのバージョンが**4.15.4以上**ならとりあえず大丈夫らしい。
自分は4.13.0-37-genericだったので、カーネルのバージョンアップが必要だった。

##カーネルのバージョンアップ
UkuuというGUIで簡単にバージョンアップが行える便利なものを入れます。

```bash:ukuu
$ sudo apt-add-repository -y ppa:teejee2008/ppa
$ sudo apt-get update
$ sudo apt-get install ukuu
$ sudo ukuu-gtk
```

するとUkuuが立ち上がるので、**4.15.4以上**のカーネルをインストールしましょう。私は4.16.0を入れました。
インストールは簡単で、入れたいカーネルのバージョンを選択し、右上のInstallボタンを押せばおっけーです。

インストールが完了したらUbuntuを再起動しましょう。

##Wi-Fiの設定を変える

まずはドライバーを[こちらから](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/endlessm/linux/tree/master/drivers/net/wireless/rtl8821ce)ダウンロードします。
次にターミナルを立ち上げます。

```bash:makefile
$ cd ~/Downloads
$ unzip rtl8821ce.zip
$ cd rtl8821ce
$ nano Makefile
```

152行目の`export TopDIR`が以下のようになっていると思います。

```
export TopDIR ?= $(srctree)/drivers/net/wireless/rtl8821ce
```

それを先ほど解凍したパスに変更します。

```
export TopDIR ?= $ ~/Downloads/rtl8821ce
```
編集がおわったら`Ctrl+o, Enter, Ctrl+x`でエディターを閉じます。
最後に以下のコードを実行すれば完了です。

```bash:modprobe
$ make
$ sudo make install
$ sudo modprobe 8821ce
```
あとは再起動してネットワークの設定画面に行くとWi−Fiが追加されているはずです。

#参照
- [Wifi not working on Lenovo ThinkPad E570](https://askubuntu.com/questions/990378/wifi-not-working-on-lenovo-thinkpad-e570)
- [How To Upgrade Linux Kernel In Ubuntu And Linux Mint Easily With Ukuu](https://fossbytes.com/install-upgrade-linux-kernel-ubuntu-mint-ukuu/)
３分ごとにマウスを動かす

##python3で３分毎にマウスを動かす
会社支給のスクリーンセーバーがうざいのをマイコンで対処したという旨のツイートを見かけたので、これはスクリプトでもできるのではという思いから書いてみました。
pyautoguiが入っていない場合pipで入れます。これはGUI環境で行ってください。
SSH等リモート接続の場合KeyErrorが発生するようです。

```
pip install pyautogui
```

```mouse.py
# -*- coding: utf-8 -*-
 
import pyautogui
import time
 
#click()でエラーが出るときはこっちを使う
def click1():
    try:
        pyautogui.click()
    except PermissionError:
        pass
 
if __name__ == "__main__":
    while True:

        #待つ(秒)
        time.sleep(180)
 
        #マウス現在地取得
        #pos = pyautogui.position()
        #print(pos)
 
        #マウス移動
        pyautogui.moveRel(-50, 0) #相対座標
        pyautogui.moveRel(50, 0)
        #マウス現在地取得
        #pos2 = pyautogui.position()
        #print(pos2)

```
波括弧で引数をくくる「引数分割束縛」について

## 発端
Vuexのドキュメントにあった
https://vuex.vuejs.org/ja/actions.html


ググラビリティが低めなのでこまった。
なんとか理解できたので、ググラビリティをあげるために投稿

## what

これが

```js
increment (context) {
  context.commit('increment')
}
```

こうかける

```js
increment ({ commit }) {
  commit('increment')
}
```

## つまり何
あらかじめ引数を`{commit}`として渡しておくことで、その関数ブロックの中で呼び出そうとした関数とか変数とかは`commit`オブジェクトのプロパティとして解決される。
なので、いちいち`context.commit()`とかしなくていい。

## 何が幸せ
すっきりかける。
そのオブジェクトのプロパティを使えば使うほどすっきりかける。

## 参考文献

https://javascript.info/destructuring-assignment#object-destructuring
https://sekaiokaeru.com/tips/javascript-argument-destructuring
製品開発を高速で成功させる3つのポイント

こんにちは。
事業会社でマネージャー担当者や営業担当者を顧客にして業務効率化を進めています。顧客が真横にいるという何とも恵まれた環境で、日々製品開発をしています。

## **この記事の対象**
- 顧客にとって役立つものを作り、いち早くリリースしたい方
- 自身やチームの努力を無駄にしたくない方
- 時間を掛けて役に立たない製品を作りたくない方

## **製品開発を高速で成功させる3つのポイント**
### **(そもそも)製品開発の成功とは**
ユーザーの困りを解決すること

### **成功のために必要なこと**
1. ユーザーの困りを理解すること
2. ユーザーが使ってもらうものを作ること
3. 限られたリソースの中で困りを解決するものを作ること

### **1.ユーザーの困りを理解すること**
ユーザーの困りが分からなければ、それに対する解決策(何らかの製品やサービス)は的外れなものとなる。困りだと思ってもその仮説を検証してから解決策を考える。

悪い例: このユーザーは営業数字を手動で集計しているなぁ。であれば自動集計出来るスプレッドシートがあったら便利だろうから作ろう！
=>ユーザーに提案してみると、手動で集計してるけどそんな時間掛からないし自身で数字の変化が把握できるから続けたいとのこと。特に困りは無く、自動化した工数は無駄になった。

良い例: このユーザーは営業数字を手動で集計しているなぁ。工数が掛かることに困ってそうだからどれぐらい工数が掛かっているか聞いてみよう => 一日10分しか掛かっておらず特に負担には感じていない=>困りは無いので特に対応しなくても良いか。

### **2.ユーザーに使ってもらえるものを作ること**
どんなに開発者が良いと思ったものを作っても、それを使うのはユーザー。プロダクトは作り上げることが目標ではなく困りを解決できることが目標なので、使ってもらえるものを作る。

#### **使ってもらえるものを作るためのポイント**
- 開発者がユーザーと同じ行動をしてみる
    - ユーザーの困りが詳細に理解出来る
    - ユーザーが気付いていない困りに気づける
    - 開発者自身が使いたいものを作ることで結果的にユーザーが使いたいものが作れる

### **3.限られたリソースの中で困りを解決するものを作ること**
開発を続けるためには、価値あるものを開発してユーザーの困りを解決して、会社(または金融機関)から予算を獲得する必要があります。また開発に携わるメンバーのモチベーション維持も必要です。
そのためには、限られた予算・限られた工数の中で最大限価値のある製品を開発する必要があります。

#### **限られたリソースで価値ある製品を開発するポイント**
自身が思っている1/10くらいバッジを小さくすること。
良いアイデアを思いついたら実装する前に仮説を検証する。

(たとえ話) 「営業数字が毎朝自動で更新されるシートを作りたい場合」
悪い例: データベースから毎朝自動でスプレッドシートにデータを書き出してそれをローデータにして実績を集計するようなシステムを開発すればユーザーの困りを解決できるのではないか?と思い全部構築してみた。
=>その結果...だがデータベースへの実積入力漏れやミスが多くて正確な数字が集計できず、結局手作業で集計することになってしまった。

良い例: データベースから毎朝自動でスプレッドシートにデータを書き出してそれをローデータにして実績を集計するようなシステムを開発すればユーザーの困りを解決できるのではないか?と思い、それが解決策になるかどうか仮説検証しようと思ったが、仮説は複数出てきたので1つずつ検証しようと思った。更新のタイミングは毎朝1度で良いか?、メンバーは100%データを漏れなく入力しているか?、ミス無く入力しているか?、どのようなUX,UIだと使いやすいか?、など。検証するためにはシステムを作らなくても良いので、まずユーザーの集計作業フローをヒアリングして自分で実際に集計してみて仮説検証した。
=>その結果...自身で集計することで自身を顧客にすることが出来たので無駄なものを作らずに改善が進められた。

## **まとめ**
顧客目線に立つために開発者自身が顧客の体験をしてみることが重要です。インタビューやデータだけでは気付かなかった困りが発見できたり、開発者自身が顧客なのでUX,UIについて自らが使いやすい形でPDCAを回すことが出来ます。
アルゴリズムについて

「アルゴリズムをはじめよう　」（伊藤静香著）を読んだので、備忘録的まとめ

# 線形探索法　
**特徴**
先頭から順々に探すアルゴリズム
単純でわかりやすい
効率はあんまよくない


とりあえず試しに、8が左から何番目にあるかを線形探索法で探すアルゴリズムを組んでみた

```
num = "12345676545671287440278174913740971846071467384127346120365107246571647016183640712365876407871473"
ary = num.split('').map(&:to_i)

i = 0
while i < ary.size
  i += 1
  break if ary[i] == 8
end

puts i
```

まず適当に数字を打ち込む（探索する対象として用意）
splitメソッドで配列として変数aryに格納
探索の終了条件を決める。今回は配列aryから８を見つけるか、全部探し切ったら終わりってことにする。

変数ｉをおき、aryを左から一個ずつ数字をみていく。
一個見るたびにｉ君は一つまた一つと成長し、その度に視座も高くなっていく。（見る数字が一個ずつ左にずれていく）

ｉ君が８を見つけた時点でループ終了
その時のiに入ってる数字を出力して、一番左側の８の場所を見つけることができました。


線形探索じゃないかもだけど、

```
ary.each_with_index do |n,i|
  
  if n == 8
    puts "8は#{i}番目にあります"
  end
end
```
これで、配列の中の全部の８の場所を探せる。
これはeach_with_indexメソッドで添字を取得しているだけだから簡単だけど、一番左側の８の場所だけ取り出したい時がなんかわからんかった。

もうちょっと研究します。

#二分探索法
**特徴**
あらかじめソートされているデータが対象
探索する範囲を半分にしながら探索する

プロセスとしては
①真ん中の要素を選ぶ作業
②真ん中のデータと目的のデータを比較する作業
③探索の範囲をもう半分に狭める作業
がある。

```
ary = "1,2,13,56,213,14253,1213421,2123313,141235253,2415245346513"
a = ary.split(',').map(&:to_i)

h = 0
t = a.size - 1
w = 213

while h <= t
  c = (h + t)/2
  if a[c] == w
    puts c - 1
  elsif  a[c] < w
    h = c + 1
  elsif a[c] > w
    t = c - 1
  end
  break if a[c] == w
end

```
とりあえず書いてみた。
まず探索する範囲のデータを用意し、配列として格納。
今回探索する目的の数字は213とした。

探索範囲の最初をh,終わりをtと置く。
探索範囲に対象物がなかった場合、処理を続けるとhとtの値の関係性が逆転するので、それを見つからなかった時の終了条件とする。
まず(h+t)/2で探索範囲の中心を探す。これをcと置く。
c番目の数が213だったら処理を終了。２１３の位置を出力する。
違った場合、cと２１３を比較し、大小の場合それぞれで場合わけする。
そんでhもしくはtの値を変更し、同じ処理を繰り返す。
対象が見つかったら処理を終わらせる。

いい感じ。
Android Architecture Components + DataBinding で LiveData を使う

## はじめに
[Android Architecture Components](https://developer.android.com/topic/libraries/architecture/index.html) を利用した設計でアプリ開発をした際、
ViewModel -> View 間をData Bindingを使って値を反映させたかったのですが、Data BindingではLiveDataをサポートしていませんでした。

## Android Studio 3.1からData BindingでLive Dataを使えるようになりました
> Updates to data binding
> This update includes several improvements for data binding:
> ・ You can now use a LiveData object as an observable field in data binding expressions. The ViewDataBinding class now includes a new setLifecycle() method that you use to observe LiveData objects.

[Android Studio Release Notes](https://developer.android.com/studio/releases/index.html#3-1-0) に書いてある通り、Android Studio 3.1から LiveData を OservableField として使えると書いてありますので、試しに使ってみました。

## サンプル
ボタンを押すと、押した回数がカウントされて、Viewに表示するだけの機能です。

```kotlin:MainViewModel
class MainViewModel : ViewModel() {

    var text: MutableLiveData<String> = MutableLiveData()
    private var count = 0

    fun onClick(view: View) {
        count++
        text.value = "count: $count"
    }
}
```

```kotlin:MainActivity
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val binding = DataBindingUtil.setContentView(this, R.layout.activity_main) as ActivityMainBinding
        val viewModel = MainViewModel()

        // ここがポイント
        binding.setLifecycleOwner(this)
        binding.viewModel = viewModel
    }
}
```

```xml:activity_main.xml
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    >

    <data>

        <variable
            name="viewModel"
            type="jp.yourmystar.livedatabinding.MainViewModel"
            />
    </data>

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

        <TextView
            android:id="@+id/countText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{viewModel.text}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            />

        <Button
            android:id="@+id/countButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{viewModel::onClick}"
            android:text="Button"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/countText"
            />

    </android.support.constraint.ConstraintLayout>
</layout>
```

重要な部分は`MainActivity`で、`ViewDataBinding#setLifecycleOwner(LifecycleOwner)` を使っているところです。
これがないと値が反映されません。
csvファイルをmysql5.7にimportする方法

#csvファイルをmysql5.7にimportする方法

##背景
データがcsvで共有されているため、それを手元のmysql5.7に入れたい。

##/var/lib/mysql-files/に移動
移動しないと以下のエラーが出る
```ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
```

##importする
linuxサーバではdefaultではセキュリティーの問題でLOAD DATA LOCALコマンドが使えなくなっている。
以下のようなエラーが出る。
```ERROR 1148 (42000): The used command is not allowed with this MySQL version
```
###mysql接続時に--local-infile=1オプションを渡す。
```
mysql -uuser -ppassword -hhost --local-infile=1
```
https://dev.mysql.com/doc/refman/5.6/ja/load-data-local.html

##load dataコマンド使い方
```
LOAD DATA LOCAL INFILE '/var/lib/mysql-files/hoge.csv' INTO TABLE table FIELDS TERMINATED BY ',' ENCLOSED BY '"' IGNORE 1 LINES;
```
TERMINATED BY　区切り文字

ENCLOSED BY　フィールドを囲むキャラクタ

IGNORE 1 LINES　何行importしないか

##詳しいオプション
https://dev.mysql.com/doc/refman/5.6/ja/load-data.html
WindowsでのGithub接続方法

様々がエラーで苦しんだのでメモ

まず、Githubにつなげたいプロジェクトフォルダを開く。
表示タブを開き、「隠しファイル」にチェックを入れる。
.gitファイルが表示されるので削除。

そこからは通常通り
'''git init'''
'''git remote add origin (GithubのhttpのURL)'''
'''git add .'''
'''git commit -m "Initial commit"'''
'''git push origin master'''
CentOS7でWebサーバー（LAMP環境）を構築する前に考えておくとよいこと

#CentOS7でWebサーバーを構築すると...

Apache　2.4.6
PHP　5.4系
mariaDB　5.5.56

になります。

余談ですが、
PHPが5.4系で古いですが、実は新しい？です。
ContOSに入っているPHPはベンダーサポートが付くので、CVEの対応はバックポートでパッチが充てられていたりしてバージョンそのまんまのPHPとは違うものになっています。
そして、ベンダーサポートの期間は相当長いのです。
なので、このPHP5.4は安全かつ保証の長いものだと思います。

##何を考えておけばよいのか

－Laravelなどの新しいPHPフレームワークを使う可能性はあるのか。
－http2.0は使わないか。

です。
もしそれぞれ必要であればデフォルトのApacheとPHPはアンインストールして入れ直しになります。
なので、何も考えないで色々インストールや設定を進めているとあとで面倒くさいことになること間違いないです。

また、MariaDBも5.5系で古いので、場合によっては5.6系に入れ直した方がよいかもしれません。それも考慮し、バージョンを決めてから設定を始めた方がよいかと思います。

#PHP、Apacheのインストールについて

Laravel5.5はLTSになっているので、現時点でLaravelを使うなら5.5がよいと思いますが、その場合PHPは7を入れる必要があります。
インストール方法は様々なサイトで紹介されていますので割愛しますが、さらっと記載しますと、

・すでにPHPがインストールされている場合は yum removeで削除する
・remiリポジトリを追加する
・yum install --enablerepo=remi,remi-php72 php
という感じでインストールします。

http2.0を使う場合、Apacheは2.4.17以上が必要です。
※2.4.17以上でもhttp2のモジュールが使用できなくなったバージョンがありますので、そのバージョンは避ける必要があります。

httpdの新しいバージョンをインストールする方法も様々なサイトで紹介されていますので詳細は割愛しますが、

・すでにApacheがインストールされている場合は yum removeで削除する
・iusリポジトリを追加する
・yum install --enablerepo=ius httpd24u

とします。
※2018年3月末時点では2.4.29になります。
　iusリポジトリはCentOSのお墨付きのリポジトリですので、信用してもよいと思います。

---
###ここで、少し問題があるので補足します。
httpd2.4.29なのですが、脆弱性の対応がまだされていないものになります。

現時点での最新は2.4.33で、これが安定版となります。ただ、このバージョンiusでもまだ配布されていないのです。。

[https://www.apache.org/dist/httpd/Announcement2.4.html]
にて2.4.29～2.4.33のチェンジログを確認できます。いくつかCVE対応があり、DoS攻撃を受けるような脆弱性も対応されています。なので、2.4系は2.4.33をコンパイルした方が現時点では安全です。

---
http2.0を使う場合,
openSSLのバージョンも1.0.2以上必要です。CentOS7ではデフォルトで1.0.2k-fipsなので、問題ありません。
環境構築　006　Eclipse 4.6 Neon 3 + Spring Boot スタータープロジェクト作成

#1. 概要
Spring initializr 雛形生成Webサービス経由で、Spring スターター・プロジェクトを生成

#2. Java パースペクティブ

Eclipseの[メニューバー・ウィンドウ]-[パースペクティブ]-[パースペクティブを開く]-[**その他**]をクリック

![spring-boot-001.PNG](https://qiita-image-store.s3.amazonaws.com/0/244997/34248b6e-54e2-085c-4f17-23c369f67e2d.png)

パースペクティブを開く画面が表示、「**Java（デフォルト）**」をクリック

![spring-boot-002.PNG](https://qiita-image-store.s3.amazonaws.com/0/244997/e04e05be-63f5-e95e-49bb-970c0fe61f7e.png)

#3. Spring Boot ウィザード

パッケージ・エクスプローラー上で右クリック、[新規]-[**その他**]をクリック

![spring-boot-003.PNG](https://qiita-image-store.s3.amazonaws.com/0/244997/96b3d29b-3c01-e4a8-24e4-dce0a99327cd.png)

ウィザード選択画面が表示、[Spring Boot]-[Spring スターター・プロジェクト]を選択、「**次へ**」をクリック

![spring-boot-004.PNG](https://qiita-image-store.s3.amazonaws.com/0/244997/0e8d02b3-fb58-2bbd-dd87-09970dd3e6e9.png)

新規 Spring スターター・プロジェクト 画面が表示
※　デフォルト設定のままでも可、今回は、『Maven』ではなく『Gradle』を使う予定

![spring-boot-005.PNG](https://qiita-image-store.s3.amazonaws.com/0/244997/eabfdafe-e086-79be-0708-d51fe6964743.png)

型：を『Gradle（Buildship 2.x）』に変更、その他（名前、グループ、成果物 ・・・）を適宜変更、「**次へ**」をクリック

![spring-boot-006.PNG](https://qiita-image-store.s3.amazonaws.com/0/244997/31066848-457d-3ef7-9554-8ded812290ea.png)

『Spring Boot Version』と機能を実現するのに必要なライブラリを『使用可能』テキストに入力・検索し選択
下記は、lombokライブラリ（超訳：使用すればgetterメソッド・setterメソッドをコード上に直接書かなくて済む）を選択したキャプチャ

![spring-boot-007.PNG](https://qiita-image-store.s3.amazonaws.com/0/244997/df3dc4bb-5591-f662-4efd-29adfc046de1.png)

その他、必要なライブラリを選択、「**次へ**」をクリック

![spring-boot-010.PNG](https://qiita-image-store.s3.amazonaws.com/0/244997/41cdbeec-feb7-3411-6eae-b6ee5eb5e506.png)

選択したライブラリを含む、Spring initializr 雛形生成WebサービスのURLが生成されるので、「**完了**」をクリック

![spring-boot-011.PNG](https://qiita-image-store.s3.amazonaws.com/0/244997/c3368570-c503-43ed-b04d-d0642953c283.png)

必要なライブラリが、Mavenリポジトリからダウンロードされる

![spring-boot-012.PNG](https://qiita-image-store.s3.amazonaws.com/0/244997/4c79e709-c355-8d6c-8236-0c5b0da846c0.png)

ダウンロードが完了すると、雛形となるプロジェクト構成が出来上がる

![spring-boot-013.PNG](https://qiita-image-store.s3.amazonaws.com/0/244997/54b57c76-c31f-885d-83d3-8a0e13a04121.png)


![spring-boot-014.PNG](https://qiita-image-store.s3.amazonaws.com/0/244997/e07761cd-ce2c-a7e3-daee-88813e909453.png)


![spring-boot-015.PNG](https://qiita-image-store.s3.amazonaws.com/0/244997/6ee32d30-44d3-6396-f29f-03c1d95575f8.png)
Tableau Server on Linuxのアップデート

ほぼ毎月のようにアップデートパッケージが配信されるTableauです。今回はTableau Server on Linuxのアップデート方法です。

ここで一言。。。

**Tableauさん、yumのリポジトリ作ってください！**

ダウンロードが面倒です。。。
手順としては難しくないのですが。。。
ダウンロードが面倒です。。。

以下手順です。

https://www.tableau.com/support/releases/server
から該当バージョンをクリックするのですが、"Released..."をクリックしてダイレクトリンクに行きましょう
ページが表示されたら、下部にダイレクトリンクされたパッケージ名称があります。
ここで右クリックしてURLコピーをします。

10.5.2の場合は以下になります。
https://downloads.tableau.com/esdalt/10.5.2/tableau-server-10-5-2.x86_64.rpm
すぐにわかると思いますが、次のバージョンはきっとあそこが変わるんだろうということがわかります。
でも、それを考えるのが面倒なので、もう一度書きます。

**Tableauさん、yumのリポジトリ作ってください！**

あとは、日本語化が追い付いていないようですが、
http://onlinehelp.tableau.com/current/server-linux/en-us/upgrade_linux.htm
を参考にして以下のようにします。

```shell-session
wget https://downloads.tableau.com/esdalt/10.5.2/tableau-server-10-5-2.x86_64.rpm
tsm stop
sudo yum install tableau-server-10-5-2.x86_64.rpm
sudo /opt/tableau/tableau_server/packages/scripts.10500.18.0305.1200/upgrade-tsm --accepteula
tsm start
```

簡単ですね。

`sudo /opt/tableau/tableau_server/packages/scripts.10500.18.0305.1200/upgrade-tsm --accepteula` の `10500.18.0305.1200` 部分はバージョンによって変わるはずですので、yum install 後のメッセージに従ってください。
埋め込んだPDFを印刷させない方法（PDF.js）

## はじめに

- PDF.jsを使用
- そのものをいじリます
- 全てCSSだけで対応可能
- PDF直接見られた時は対応不可（一般ユーザはそこまでたどり着かないと想定）

## 実装方法

### まず埋め込む
```html

<iframe src="web/viewer.html?file=../sample.pdf"></iframe>
```
ファイルのパスは適宜変更。

### 印刷時、PDF部分を表示させない
viewer.cssに下記追加

```css

@media print {
  body {
    display: none;
  }
}
```
印刷画面では、エリアだけ保持され、その部分が表示されない。
開発者しかやらないと思うが、仮に埋め込んだURLにアクセスされ、そこで印刷しても表示されない。
※PDF本来のURLに直アクセスされれば、印刷もDLもできてしまうが、一般ユーザの操作ではそこまでできないと想定

### 余分なボタンを消す

さっきと同じく、viewer.cssに下記追加。

```css

#print, #secondaryPrint {
  display: none !important;
}
```
ブラウザ上で操作される印刷ボタンを消す
↓こういう部分
![toobar.png](https://qiita-image-store.s3.amazonaws.com/0/232821/92f2d2f3-7844-09b5-dd10-7a5af0e5da02.png)

![toobar2.png](https://qiita-image-store.s3.amazonaws.com/0/232821/8ca566ae-a624-5669-7958-8c7338cb4504.png)

ダウンロードもさせたくなければ、適宜IDを調べて、そのボタンも消す。


### ツールバーを消す

いっそのことツールバーを消したほうがスッキリかも…？
その場合は、ツールバーの高さ分だけ変な余白ができるので、```#viewerContainer```の位置を調整する。

```css
.toolbar {
  display: none;
}
#viewerContainer {
  top: 0;
}
```
ORACLE APEX5.1.4 パッチ適用メモ（12.2のPDBにインストール PL/SQL Gateway版）

**1. OTNのサイトから「Oracle Application Express 5.1.4 Patch Set」のダウンロード**

http://www.oracle.com/technetwork/developer-tools/apex/downloads/index.html


**2. パッチを適用するサーバーの任意のディレクトリ（ここでは/tmp）に解凍し、移動**

```
> unzip p26795231_514_Generic.zip -d /tmp
> cd /tmp/patch
```


**3. SYSユーザーでログインし、インストールするPDBに接続**

```
> sqlplus / as sysdba
SQL> ALTER SESSION SET CONTAINER = ORCLPDB;
```

**4. PL/SQL Gatewayの無効化**

* 現在のポート番号確認

```
SQL> SELECT DBMS_XDB.GETHTTPPORT FROM DUAL;

GETHTTPPORT
-----------
       xxxx

1 row selected.
```

* 無効化

```
SQL> EXEC DBMS_XDB.SETHTTPPORT(0);
SQL> COMMIT;
```

**5. パッチ適用**

```
SQL> @apxpatch.sql

（途中略）

PL/SQL procedure successfully completed.

timing for: Complete Patch
Elapsed: 00:06:36.63
SQL>
```

**6. Imagesディレクトリの更新**

```
SQL> @apxldimg.sql /tmp/patch

（途中略）

Directory dropped.

timing for: Load Images
Elapsed: 00:01:45.11
SQL>
```

**7. PL/SQL Gatewayの有効化**

```
SQL> EXEC DBMS_XDB.SETHTTPPORT(<手順4で確認したポート番号>);
SQL> COMMIT;
```
VirtualBoxにCentOS 7.4をインストール

忘れそうなので、テンプレートとして使用するCentOSの最新版をインストールする手順をメモ

# 構成
Windows7 Pro(32bit)
インストールするホストマシン

VirtualBox 5.2.8
ゲストOSをインストールするVM

CentOS 7.4.1708
ゲストOS、公式から64bitのminimalを取得
余計なものをインストールしたくないので、minimalを使用

# VirtualBoxにCentOS 7.4をインストール
1. VirtualBoxを起動して、`VirtualBoxマネージャー`で新規ボタンを押す
![01.png](https://qiita-image-store.s3.amazonaws.com/0/172103/1c545802-1d65-3c56-b97c-0921a0c0c0fa.png)

2. `仮想マシンの作成 - 名前とオペレーティングシステム`で以下のように設定し、次へボタンを押す
名前：CentOS74-Test 
タイプ：Linux 
バージョンRed Hat(64bit) 
![02.png](https://qiita-image-store.s3.amazonaws.com/0/172103/bf3c048f-2bca-3770-b749-a84c92d1babd.png)

3. `仮想マシンの作成 - メモリーサイズ`で`512MB`に設定し、次へボタンを押す
あんまり、多く割り振るとVMを起動中、他の作業に影響がでるので、渋々
![03.png](https://qiita-image-store.s3.amazonaws.com/0/172103/0540adc3-2bb5-5975-3980-96a3ba3af0aa.png)

4. `仮想マシンの作成 - ハードディスク`で`仮想ハードディスクを作成する`に設定し、作成ボタンを押す
![04.png](https://qiita-image-store.s3.amazonaws.com/0/172103/7241da0d-ee18-295f-85e7-9b1b57b57e2d.png)

5. `仮想マシンの作成 - ハードディスクのファイルタイプ`で`VDI（VirtualBox Disk Image）`に設定し、次へボタンを押す
![05.png](https://qiita-image-store.s3.amazonaws.com/0/172103/e7cf8104-0982-fcfd-9cc9-803d96d8acd1.png)

6. `仮想マシンの作成 - 物理ハードディスクにあるストーレージ`で`可変サイズ`に設定し、次へボタンを押す
![06.png](https://qiita-image-store.s3.amazonaws.com/0/172103/dc7d6622-ab8a-c00d-63f7-a3394aeb1527.png)

7. `仮想マシンの作成 - ファイルの場所とサイズ`はデフォルトのまま、作成ボタンを押す
![07.png](https://qiita-image-store.s3.amazonaws.com/0/172103/7c5455d0-a8ca-e0ee-a70e-7b7b9942e399.png)

# ネットワークアダプタ設定
※本当だと、このタイミングで起動ボタンを押してゲストOSをインストールするけど、先に`ネットワークアダプタ`の設定をする
1. `VirtualBoxマネージャー`で設定ボタンを押す
![08.png](https://qiita-image-store.s3.amazonaws.com/0/172103/66bc203d-9f6a-7c5a-a79e-a861603b8786.png)

2. `CentOS74 - Test - 設定`の左ペインで`ネットワーク`という項目を選択し、`アダプター2`タブを選択
![09.png](https://qiita-image-store.s3.amazonaws.com/0/172103/606a1565-7721-c695-10fe-e45782e2d262.png)

3. `ネットワークアダプターを有効化`をチェック
4. `割り当て`に`ホストオンリーアダプター`を選択し、OKボタンを押す

# ゲストOS（CentOS7.4）をインストール
1. `VirtualBoxマネージャー`で起動ボタンを押す
2. 起動ハードディスクを選択で`CentOS-7-x86_64-Minimal-1708.iso`を選択し、起動ボタンを押す
あとは、通常のOSインストールを行う

次回は、初期設定を書く
【vim】viコマンドで方向キーがABCDってなる問題

```
vi ./sample.txt
```
方向キーポチポチー

```
A
A
A
A
B
B
B
B
B
hogehoge
```

↑うざい

原因を調べたら、ついでにviとvimの関係性も分かったのでメモ。

# 対処法

```
$ touch ~/.vimrc
$ vi ~/.vimrc
```
vimの設定ファイルを作って開いて（既にあればtouchしない）

```.vimrc
set nocompatible
```
終わり

# viとvimの関係

ん？viの挙動を直すのにvimとやらの設定ファイルを書いた？

->vimについて少し調べた

vi: Visual Interface の略。マウス使わないテキストエディタ。
vim: Vi Improved の略。その通り改良版vi。

viを起動すると、シンボリックリンクでvimを開いているらしい

```
$ ls -l /usr/bin/vi
lrwxrwxrwx 1 root root 20 Jan 14  2016 vi -> /etc/alternatives/vi
$ ls -l /etc/alternatives/vi
lrwxrwxrwx 1 root root 18 Jan 14  2016 /etc/alternatives/vi -> /usr/bin/vim.basic
```
シンボリックリンクを通してvimを開いている場合、vi互換モードがONになっていることがある。
これに対して、vimの設定ファイル`.vimrc`に明示的にvi互換モードをOFFに設定する記述を行う必要がある。
それが上記の`set nocompatible`で、互換モードをOFFにしている。

つまり僕はviだと思ってvimを今まで使っていたってことか。

## 参考
https://www.soum.co.jp/misc/vim-no-susume/6/
Foundation6(Apps)で、Sassの出力先を変更する方法と問題点

#前置き
Foundation-siteを選択した場合はConfig.ymlにて出力先のパスを変更できるので、以下の内容は該当しません。

#環境
OS　CentOS7
Foundation-Cli　2.2.5

#Foundationのインストール

作業ディレクトリに移動して
`foundation new`
を実行。インストールする種類とプロダクション名を聞かれるのでそれぞれ選択＆入力する。

#ここからが本題

##困ったこと

Foundation自体でWebを公開したいわけではなかったので、Foundationで作成したプロジェクトとそれを使いたいWebのディレクトリは別で作成しました。

ところが、FoundationにはSassコンパイル後の出力先を設定するような項目がないようなのです。

これでは、Sassファイル編集後に
`Foundation watch`
で、作成されるコンパイル済みのCSSやJSをWebのディレクトリに移動させるという手間が発生してしまいます。

##やりたいこと
`Foundation watch`
で生成されるCSS、JSの出力先を変更したい！

##やったこと
gulpfile.js　を直接編集しました。

var paths で定義されている変数の最後に

```
  build: './../../../../../public/foundation/',
```
を追加します。
そして、

```
'build'
や
'./build'
```
になっているところを

```
paths.build
```
に修正します。結構あります。
※'build/xxxx/xxxxx'　のような場所はJSの文字列結合を使って、
　paths.build+'/xxxx/xxxxx'
　にします。

#問題点
おそらくFoundationの重要なシステムファイルであろうgulpfile.jsを直接編集したので、Foundationのアップデートをしようとした際に何か問題が発生したり、gulpfile.jsを都度修正しなおさないといけなかったりする可能性があります。

---
上記方法でやりたいことは実現できたのですが、そもそも出力先が変更できないとか普通に考えてないだろうとも思っています。
なので、きっと何か方法があるのではないでしょうか。
（スミマセン。アマリシラベテナイノデス。）
知っている人、是非教えてやってください。
Flowによる静的型チェック

##Flowとは
Flowは***JavaScriptに静的型チェックの機能を追加するもの***です。
静的型付き言語では書いたコードの型が間違っているとエラーが出て、間違いに素早く気づくことができます。
JavaScriptは静的型付き言語ではなく静的型チェックを行えません。
FlowではJavaScriptに静的型チェック機能を追加するライブラリ。

###No.1 Flowのセットアップ
ここではReact NativeにFlowをセットアップする方法を示します。
雛形の作成(react-native init)でFlowの設定ファイルである「.flowconfig」が自動で生成されています。
＊設定ファイルは自動で生成されていますが、ライブラリ自体はインストールされていません。
#####1. 設定ファイルからバージョンを確認する
```bash:バージョンを確認
cat .flowconfig

[ignore]
; We fork some components by platform
.*/*[.]android.js

; Ignore "BUCK" generated dirs
<PROJECT_ROOT>/\.buckd/

; Ignore unexpected extra "@providesModule"
.*/node_modules/.*/node_modules/fbjs/.*

; Ignore duplicate module providers
; For RN Apps installed via npm, "Libraries" folder is inside
; "node_modules/react-native" but in the source repo it is in the root
.*/Libraries/react-native/React.js

; Ignore polyfills
.*/Libraries/polyfills/.*

; Ignore metro
.*/node_modules/metro/.*

[include]

[libs]
node_modules/react-native/Libraries/react-native/react-native-interface.js
node_modules/react-native/flow/
node_modules/react-native/flow-github/

[options]
emoji=true

module.system=haste

munge_underscores=true

module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'

module.file_ext=.js
module.file_ext=.jsx
module.file_ext=.json
module.file_ext=.native.js

suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FlowFixMeProps
suppress_type=$FlowFixMeState

suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError

[version]
^0.65.0
```
#####2. バージョンを指定してインストール
```bash:インストール
npm install --save-dev flow-bin@0.65.0
```
*＊開発時にしか使わないため「--save-dev」にする*

###No.2 Flowを使う
#####静的型チェックを行う関数を作成
```javascript:App.js
//プログラムの最下部に記載

// @flow
function increment(n: number): number {
    return n + 1;
}
increment("3"); // Error!
```

###No.3 Flowを実行する(エラー)
Flowを使って静的型チェックを行う

```bash:Flownの実行
`(npm bin)`/flow
```

*＊1回目の実行はFlowのサーバプロセスを立ち上げるため時間がかかる*



```bash:Flow実行結果
Error: App.js:13
 13: } from 'react-native';
            ^^^^^^^^^^^^^^ react-native. Required module not found

Error: App.js:64
 64: square("2");
            ^^^ string. This type is incompatible with the expected param type of
 61: function square(n: number): number {
                        ^^^^^^ number


Found 2 errors
```

###No.3 Flowを実行する(正常)
#####エラー箇所の修正
```Bash:エラーの修正
vi App.js
```

```javascript:エラーの修正
increment(3);
```

#####Flow実行(正常)
```bash:Flow実行
`(npm bin)`/flow
No errors!
```

##あとがき
・npmで簡単にライブラリを追加できるので後からFlowを追加することが可能
・React Nativeでアプリを開発する場合、最初からFlowを導入した開発が推奨されています。Flowの型チェックで「インターフェースのわかりやすさ」「リファクタリングのしやすさ」など使用しない理由が見つからない。
・Flowを利用することで型チェックを導入した開発がReact Nativeでも簡単に行える。
Ruby で「パスカルの三角形」を出力（ちょっと関数型プログラミングっぽく+メモ化）

#パスカルの三角形
こういうのですね。

```
              1               
             1 1              
            1 2 1             
           1 3 3 1            
          1 4 6 4 1           
        1 5 10 10 5 1         
       1 6 15 20 15 6 1       
     1 7 21 35 35 21 7 1      
```

$(a + b)^n$を展開すると、係数が上のように並びます。両端が 1 で、となり同士の数字を足すと、その下の数字になっています。
#コード

```ruby:pascal.rb
each_cons = ->(ary) {
  (ary.size < 2) ? [] : [ary[0] + ary[1]] + each_cons.(ary.drop(1))
}
pascal = ->(n) {n.zero? ? [1] : [1] + each_cons.(pascal.(n - 1)) + [1]}

n = 8
n.times {|i| puts pascal.(i).join(" ").center(30)}
```

これで上の出力になります。「関数型」ってのはまあ気分です。誰でも何でも再帰で書きたいときがある（笑）　結構きれいに書けたと思うのだけれど、もっと上手いやり方があったら教えて下さい。

関数`pascal.(n)`というのは n + 1 行目の出力というつもりで書きました。Array を返します。順番に`[1]`,`[1, 1]`, `[1, 2, 1]`, `[1, 3, 3, 1]`... みたいな感じですね。

関数`each_cons.(ary)`は Ruby 組み込みから名前を借りただけで、自前の関数です。このプログラムは**この関数がキモです**。再帰関数（自分自身を呼び出す関数）です。関数型プログラミングでは**ループの代わりに再帰**を使います。上で「となり同士の数字を足すと、その下の数字になっています」と書きましたが、ここではまさにそれをやっています。おわかりでしょうか。引数`ary`は Array で、関数は Array を返します。

###Rubyをよく知らない人へ
もしかしたら`->() {}`という書き方をご存知ない方がおられるかもしれないので書いておくと、これは Ruby の lambda の書き方のひとつです。`lambda do ~ end`と同じです。また、` ? : `というのはいわゆる「三項演算子」で、`if then ~ else ~ end`と同じです。

ちなみに、`drop(1)`というのは Lisp の`cdr`を Ruby で書いたものです。Array の先頭を取り除き、その残りを返します。例えば、`[1, 2, 3].drop(1)`は`[2, 3]`が返ります。わかる人はわかると思いますが、じつは **Ruby でちょっと Lisp っぽく**書いてみたかったのです（笑）　Lisp はよくは知りませんが。

以上は[ブログ記事](http://obelisk.hatenablog.com/entry/2018/01/31/225010)を元にしています。
#追記：メモ化
このままだと「効率が悪い」としかられそうなので、先に追記しておきます。こんな風にします。

```ruby:pascal_memoized.rb
memo = {}

each_cons = ->(ary) {
  (ary.size < 2) ? [] : [ary[0] + ary[1]] + each_cons.(ary.drop(1))
}
pascal = ->(n) {
  return memo[n] if memo.has_key?(n)
  memo[n] = n.zero? ? [1] : [1] + each_cons.(pascal.(n - 1)) + [1]
}

n = 8
n.times {|i| puts pascal.(i).join(" ").center(30)}
```

一度計算したものはハッシュ`memo`に入れておくという「メモ化」なる技法です。高速化などによく使われます。多少コードの量は増えますが、計算量をぐっと減らすことができます。

それから、`n.times {...}`の部分ももちろん簡単に再帰で書けます。徹底したい方はそちらでどうぞ。
New Tab Draft - Clean and Convenient 

A whole new way to use your Chrome Tab. Open a new tab to take notes, inspirations and make calculations
New Tab Draft focus on cleaner & simpler writing experience on Chrome.

----

#Easy
You can just open a new tab and write down whatever you want.
Next time you open a new tab, things you typed last time will still be there. 

#Note List
You can create multiple drafts for your need.

#Protect your privacy
New Tab Draft help you save it in your browser not on the server.
In the latest version we added a function which will blur your draft when you don't use Chrome in 10 minutes.

#Calculation
You can also make calculation on New Tab Draft.
Type "5*7+9" and press Enter, you will get "5*7+9=44". Isn't it very simple and cool?

#Customization
Customize font and background to make it your own way.

People use New Tab Draft to take notes, write down inspiration, calculation... whatever you want.

Try it. You will not be disappointed.

##Download 
[Visit Home Page](https://chrome.google.com/webstore/detail/new-tab-draft/nmfjkeiebceinkbggliapgfdjphocpdh?utm_source=qiita)

##Screenshots
![1.png](https://qiita-image-store.s3.amazonaws.com/0/247076/a43b2b19-d647-186a-a1de-5cbc2b0edf4e.png)

![2.png](https://qiita-image-store.s3.amazonaws.com/0/247076/395d7ee1-8a7d-6e3e-05cd-9031f05016ea.png)

![3.png](https://qiita-image-store.s3.amazonaws.com/0/247076/d7ff7724-cf55-ac1f-b37f-be7d3038be50.png)

![4.png](https://qiita-image-store.s3.amazonaws.com/0/247076/f7698bfd-241a-b0fe-e858-86ed0ca0424e.png)

![5.png](https://qiita-image-store.s3.amazonaws.com/0/247076/571871ca-faa2-00cf-61a2-d59512385e82.png)
[テスト公開中]LightFile Simulatorを使って、画像最適化できるかチェックしてみよう

弊社の製品でLightFileという画像最適化ツールがあるのですが、その効果がどのくらい得られるをシミュレートできるサイトを公開しました。フィードバックもほしいので、ガリガリ使ってみてください。

- [LightFile Simulator](https://simulator.lightfile.net/)

使い方はこちらのブログ記事を参考にどうぞ。

- [LightFile Simulatorの使い方のブログ記事](https://blog.ideamans.com/2018/03/lightfile-simulator.html)

## LightFile Simulatorでなにがわかるの？

![URLでシミュレートした場合のレポート画面](https://blog.ideamans.com/images/2018-03-26-lf-simulator15.jpg)

**シミュレータでは、画像を最適化すると、どのくらいファイルサイズが減るのかを確認することができます。**

方法は、画像単体（ドラッグアンドドロップ）か、URLを入力してそのページの画像がどこまで最適化できるのか？というのがわかります。レポートされる項目は以下のとおりです。

### 画像単体をシミュレートした場合

- オリジナル画像のファイルサイズ
- LightFileで処理したあとのファイルサイズ（３パターン）
- LightFile処理後の画像ファイル

### URLでページをシミュレートした場合

- 画像単体でシミュレートした場合と同じレポートが、画像分レポートされる
- そのページの総ダウンロードファイルサイズ
- そのページのダウンロードされるコンテンツの種類（font, image, js, css など）の割合
− そのページのダウンロードされる画像のうち、拡張子ごとの割合

## レポート画面

画像単体でのシミュレート
![画像単体でのシミュレート](https://blog.ideamans.com/images/2018-03-26-lf-simulator05.jpg)

URLでページでのシミュレート
![ページでのシミュレート：コンテンツの割合](https://blog.ideamans.com/images/2018-03-26-lf-simulator14.jpg)

## LightFileってなに？

**Node.jsを利用した画像最適化ツールです。AWS Lambdaで動作するほか、Linuxでも動くようにオンプレ版を用意しています。**

JPEGminiとか、TinyPNGとか、いろいろな画像最適化ツールが世の中には存在します。Akamai Image Managerや、Cloudinaryという海外製のサービスもたくさんあります。それらと同じと思っていただいて構いません。CDNのありなしとか、対応拡張子とかに違いはありますが、画像をキレイに軽量化するという大枠では同じです。

## 注意事項

テスト公開中なので、動作が不安定だったり、止まったりすることもあります。ご了承ください。

## 参考

- [LightFile | 自動でJPEGファイルを容量削減 表示の高速化/転送量の削減を同時に実現](https://core.lightfile.net/)
PWA Tokyoに参加してきたメモ

## スライド一覧
https://drive.google.com/drive/folders/0B55wxScz_BJtV1lGbTBOYlhLTVk)

## 会場の様子、雰囲気など
https://togetter.com/li/1153523

## はじめてのPWA
https://codelabs.developers.google.com/codelabs/your-first-pwapp-ja/#0

## Q&A

Q. オフラインでも使える？
A. 前回の情報（またはデフォルト値）を表示し、一定時間内（120秒など）にオンラインデータを取得できればそれを表示する仕組み（前回の情報は基本ずっと残り続ける。永続Cookieなイメージ？）

Q. 初回表示が遅い
A. AMPを使う。初回高速化=AMP、２回目以降=PWAを組み合わせる

Q. 広告表示が遅い
A. amp_for_adを使う

Q. PWAの場合の広告表示は？
A. ネイティブアプリと同じ

Q. ネイティブアプリがいらなくなる？
A. すでに完成度の高いネイティブアプリがあるのなら、PWAに作り直すものではない。

Q. PWAに最適なフレームワークは？
A. JavaScriptで作ってください、とのこと。個人的に「データ取得できたら表示」する機能があReact,Vue,Anuglarを利用すれば使いやすいのかなと思いました。

Q. 最新データがたくさんある場合は、ユーザに確認ボタンを押させる
A. Twitterみたいな「最新○件表示」ボタン

Q. Push通知の許可
A. 味気ないブラウザのプロンプトのため、サイト上でユーザーが通知を欲しいと思わせるよう誘導してから表示させる。

## PWAとは関係ないQ&A

Q. 長いローディング画面を出すなら
A. クロスワードゲームなどを表示させれば離脱しなくなる

Q. 決済情報、配送住所の取得はPayment Request APIを使おう
A. フォームの入力を選択式にできる入力補助API
:https://developers.google.com/web/updates/2016/07/payment-request?hl=ja

## 感想

日本はインフラが整っているため通信が切れる状態があまりないので、そこまでメリットはないのかなと感じました。
インフラ環境が整っていない国では必須な技術だと感じました。
【iOS/Android】Firebaseプロジェクトを開発環境と本番環境で分ける方法

# 概要
Firebaseを使用していると開発時や本番ビルド時に参照するプロジェクトを
変更したくなることがあると思います。
いくつかやり方がありますがその中で自分がもっともシンプルでわかりやすいやり方だと思う方法を記載致します。

#事前準備
Firebase console上に開発、環境本番環境二つのプロジェクトを作成しておくこと

#iOSの場合
1.それぞれの環境のGoogleService-Info.plistをダウンロードする

2.上記で作成したplistをXcodeに組み込む
![スクリーンショット 2018-04-02 15.01.46.png](https://qiita-image-store.s3.amazonaws.com/0/68719/169b52cd-86ee-af63-1df7-5ba88312b8ca.png)

3.debug、releaseによってplistを変更しoptionsを指定してAppDelegateにてFirebaseApp.configure()を実行する

```　swift:AppDelegate
#if DEBUG
   let fileName = "GoogleService-Info-dev"
#else
   let fileName = "GoogleService-Info"
#endif

let filePath = Bundle.main.path(forResource: fileName, ofType: "plist")
let fileopts = FirebaseOptions(contentsOfFile: filePath!)
FirebaseApp.configure(options: fileopts!)

```

4.Edit Scheme等で環境別に切り分けてビルドする。

#Android
1.それぞれの環境のgoogle-services.jsonをダウンロード

2.build.gradleに環境毎のFlavaorを追加

```kotlin:build.gradle
android {
    flavorDimensions "default"
    省略
　　　　　　　　productFlavors {
        development {
            applicationId 'jp.hogehoge.hogehoge'
        }
        production {
            applicationId 'jp.hogehoge.hogehoge'
        }
    }
}
```
3.google-services.jsonを環境毎に分けて設置

![スクリーンショット 2018-04-02 15.31.05.png](https://qiita-image-store.s3.amazonaws.com/0/68719/32e6d5a8-9f30-ab71-0795-17370dd16694.png)

4.Build VariantにてFlavaorを指定してBuild



#まとめ
調べると色々とやり方はある見たいですがこのやり方が一番シンプルかつ簡単なやり方かなと思いました。
参考になれば幸いです。
気づけばプロ並みPHP　ショッピングカート作りにチャレンジ！＃２【日記】(2018-04-02)

ソースをコピペしつつphpを学習。
入力フォーム→入力確認画面→入力完了画面
の流れで。

プログラムのコピペから学習していくタイプの本なんだけど、
別にPHPの基本を説明した本もあるので、そっちも並行してやりたくなってきた。

サニタイジング、結構重要そう
これはまた別分野として勉強しようと思えばいくらでも広げようがありそう
ES2015で即時関数を実行する

#はじめに
 ES2015を用いて「1度だけ実行する関数をimportして使う」モジュールを作るための、備忘録です。
`export default`はclassの冒頭につけるやり方しか知らず、ファイルの中身を即時関数1つだけにしたときにどうすればいいかわかりませんでした。
検索してもうまくヒットしなかったので、備忘録です。

##実装
サンプルのコードはPCかどうかを判定して、PCでなければtrueを返すという処理です。

```js:before
const isMobile = function () {
  const ua = window.navigator.userAgent.toLowerCase();
  return /iphone|ipod|ipad|android/.test(ua);
};
module.exports = isMobile;

```

```js:before.common

import isMobile from 'isMobile';

if(isMobile()){
console.log('spn');
}

```

このように書くと、importしている部分で毎回関数を実行することになります。
この機能の場合、最初に1度実行すれば毎回実行して確認する必要はありません。
なので、下記のように即時関数にすることで、実行回数を減らすことができます。

```js:after
const isMobile = (() => {
  const ua = window.navigator.userAgent.toLowerCase();
  return /iphone|ipod|ipad|android/.test(ua);
})();
export default isMobile;
```

```js:after.common

import isMobile from 'isMobile';

if(isMobile){
console.log('spn');
}
```

##おわりに
自分の備忘録のために掲載しました。
もっと効率のよいやり方やパフォーマンスのいいやり方を知っている方がおりましたら教えてください。
秀丸エディタ > regex > C > #define xxx 4096を探す > #define\t*.*\t*4096

```txt:動作環境
C++ Builder XE4
秀丸エディタ Version 8.22
```

### 処理概要

下記のような実装を探したいとする。

```
#define<\t>xxx<\t><\t>4096
```

### 手順

1. grepの実行にて「正規表現」にチェックをつける。
2. 下記のキーワードで検索する。
   - `#define\t*.*\t*4096`

例:
https://www.debuggex.com/r/Jyp_QJFmoRLlGW0E

### 留意事項

下記のような実装も結果に表れる。

```
#define XXX_YYY 40961
```
初心者向け PHPの不可解な動きをまとめました。

## はじめに

春ですね。
街を歩いていると、桜が目にとまり気分がウキウキしてくると同時に、
新入社員と思われる人もチラホラ見かけ懐かしい気分になります。

今回は、そんなPHPをこれから始める方に、
誰しもが一度は通ると思われるPHPの罠についてお伝えいたします。

## empty 関数

empty は、変数が空かどうかを判定するのに利用されます。
ただ、この「空かどうかの判定」がくせ者で、きちんと把握していなければ思わぬバグとなります。

たとえば、画面から入力された値が空かどうかの判定に使ったとしましょう。

```php5
empty($value)
```

\$value がどんな場合に、これはTrueとなるのでしょうか？

```php5
// case 1. value値が空文字列宇
$value="";
var_dump( empty($value) ); // true
// case 2. value値が文字列 0
$value="0";
var_dump( empty($value) ); // true
```

case 1 は、空文字列なので true となる、誰もが期待する動作ですね。
case 2 はどうでしょうか。なんと "0" という文字列が空判定されました。

もし画面からの入力チェックに使っていると、0 と入力したにもかかわらず、
未入力と判定され、もしかすると「必須項目が未入力です。」的なエラーが表示されるかもしれません。

実害はないかもしれませんが(?)、かっこわるいですよね。

また別のケースで、NULLと空配列で処理が分かれる場合の判定に使い、バグってしまう事もよくあります。
※空配列も 「空」と判定されます。

empty 関数を使う場合は、「思わぬ値が空と判定されないか」を常に気をつけて使ってください。

http://php.net/manual/ja/function.empty.php

## 多段三項演算子

プログラムにも慣れ、見やすい/綺麗なソースコードを書こうとする頃に顔を出してくる、
多段三項演算子問題です。

三項演算子自体はとても便利で、うまく使うとプログラムを簡潔に書くことが出来ます。

```php5
// $a が Trueの場合は $bに1を、Falseの場合は2を代入
if ($a) {
 $b=1;
} else {
 $b=2;
}
// 予め初期値として設定しておくやり方
$b = 1;
if (!$a) $b=2;
// 三項演算子を使うやり方。
$b = $a ? 1 : 2;
```

ただ、三項演算子で複雑な事を行うと思わぬ動きをします。
たとえば、下記 if 文を三項演算子で記述するとどのようになるのでしょうか？

```php5
// $a が Trueの場合は $bに1を、Falseの場合は、さらに$cを確認し$bの値を決定する。
if ($a) {
 $b=1;
} else {
  if ($c) {
    $b=2;
  } else {
    $b=3;
  }
}
```

おそらく、大半の人が以下のようなコーディングを行うとおもいます。

```php5
// $a が Trueの場合は $bに1を、Falseの場合は、さらに$cを確認し$bの値を決定する。
$b = $a ? 1 : $c ?  2 : 3;
```

では実際に、\$aと\$cに値を入れてみましょう

```php5
$a = $b = true;
$b = $a ? 1 : $c ?  2 : 3;
echo $b; // 2
```

期待値としては、\$a がtrue なので \$b が 1 であることです。
しかし、実際は \$b に 2 がはいます。一体なぜでしょうか？？

これはphpの三項演算子は左側から判定されるため、以下のように解釈されるためです。

```php5
$b = ($a ? 1 : $c) ?  2 : 3;
```

1.「\$a ? 1 : $c」 がはじめに判定され、結果 「1」となります。

2.「1 ? 2 : 3」が判定され、「2」となります。

そのため三項演算子を重ねる場合、優先度を明示するようにしましょう。

```php5
$b = $a ? 1 : ($c ?  2 : 3);
```

※ちなみに大体数の言語では、カッコなしでも上記のような解釈がされます。

## 比較演算子 ==

「==」は型変換を行った後に比較する演算子です。
しかし型変換がくせ者で、例えば以下のような比較はTrueとなります。

```php5
"hogehoge" == 0; // true
```

これは "hogehoge" を int型に変換すると 0 になるためです。
特に必要がないかぎりは、比較演算子は「===」を使うようにしましょう。

## 参照

余り使う機会が無いとは思いますが、
参照を使う場合、使った後にかならず unset を行うよう心がけましょう。

たとえば下記のように参照として使った変数を流用する場合、意図せぬ動きをします。

```php5
$array = [1, 2, 3];
foreach($array as &$v) {}
foreach($array as $v) { echo $v; } // 1,2,2
```

1つ目の foreach を抜けると、「\$v」は \$array の末尾「3」の参照を示した状態となります。
この状態で2つ目のforeachに入ると、ループの度に「\$v」が示す $arrayの末尾を更新する動きとなります。

``` php5
$array = [1, 2, 3];
foreach($array as &$v) {}
foreach($array as $v) { var_dump($array) }
// 1ループ目 => [1,2,1]
// 2ループ目 => [1,2,2]
// 3ループ目 => [1,2,2]
```

この動きを回避するには、1つ目のループの末尾で unset してあげる必要があります。

```php5
$array = [1, 2, 3];
foreach($array as &$v) {}
unset($v);
foreach($array as $v) { echo $v; } // 1,2,3
```
[学習用]初心者が Ubuntu16.0 に Ruby on rails を入れて初期画面を出すまで

#VagrantにUbuntuをインストール

```
vagrant init
```

でVagrantfileを作成します。

Vagrantfileの編集

```
config.vm.box = "ubuntu/xenial64"
config.vm.network "private_network", ip: "192.168.xx.xx"
```

この部分を編集する。

```
vagrant up
```
でUbuntuがインストール開始して自動で完了

```
vagrant ssh
```
Ubuntuにログインします。

#Railsをインストール
あとはこのまま行ごと順番に入れてエンターキーを押していくだけ。

```
$ sudo apt-get install git -y
$ sudo apt-get install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libpq-dev libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties libffi-dev
```

```
$ cd
$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
$ exec $SHELL
$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
$ echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
$ exec $SHELL
$ rbenv install 2.5.1
$ rbenv global
system
$ rbenv global 2.5.1
$ rbenv global
2.5.1
$ rbenv rehash
$ gem i rbenv-rehash
$ gem i rails
```

#Railsのプロジェクトを作成
上記だけだとまだRailsの初期画面を表示できないので

```
$ rails new myapptest
$ cd myapptest
$ rake db:create
$ rails s -b 192.168.xx.xx
```

ここまでコマンドを入れると、tcp:IPアドレス:3000　って出るので 
IPアドレス(192.168.xx.xx:3000)をブラウザに入れてエンターキー。

これで無事にブラウザに

Yay! You’re on Rails!

が表示されました。

##補足
いろんなサイトを見て初めてインストールから初期画面まで無事完了しました。
詳しく書いて無事動作まで行ける参考にしたサイトは以下になります。
http://satolabo.synology.me/web/install-ruby-on-rails5-ubuntu/
zsh-autosuggestions がゴミを残す


[zsh-users/zsh-autosuggestions](https://github.com/zsh-users/zsh-autosuggestions#configuration) はコマンドラインに入力された文字列からヒストリを検索し補完候補をグレイアウトした状態で提示してくれます。補完候補を使わないときはそのまま **<kbd>^M</kbd> を押せばグレイアウトした候補が表示から消え** てそれまで入力した内容が実行されます (zsh でいう <kbd>^M</kbd> や <kbd>enter</kbd> などに bind された `accept-line` widgets が実行される)。

それが何らかの原因で「<kbd>^M</kbd> を押せばグレイアウトした候補が表示から消え」なくなります (ゴミを残す)。

つまりどういうことかというと、たとえば `ls` まで打ったときに補完候補として `/hogehoge` が出ているとします (`|` はカーソル)。

```console:
% ls |/hogehoge
```

このとき通常なら <kbd>^M</kbd> を押すと

```console:
% ls
hoge.txt
% |
```

のように補完候補が消えて `ls` が実行されるわけですが、その補完候補が消えなくなりゴミを残すようになることがあります。

```console:
% ls /hogehoge
hoge.txt
% |
```

`ls` の後ろに `/hogehoge` が残っています。ただしゴミは表示上だけで `ls` に `/hogenoge` が渡されることはありません。


この原因として <kbd>^M</kbd> に別の widget が bind されている可能性が高いです。通常なら以下のように `accept-line` が bind されていますが、

```console:
% bindkey | grep '\^M'
"^M" accept-line
"^[^M" self-insert-unmeta
```

何らかの理由で以下のようにそれ以外が bind されてしまうこともあります (以下の例の「何らかの理由」は [rhysd/zsh-bundle-exec](https://qiita.com/Linda_pp/items/cb047fb1fe279f9d0b22) をインストールしたことにより <kbd>^M</kbd> に別の widget `auto_bundle_exec_accept_line` が bind された)。

```console:
% bindkey | grep '\^M'
"^M" auto_bundle_exec_accept_line
"^[^M" self-insert-unmeta
```

zsh-autosuggestions には zsh の変数として `ZSH_AUTOSUGGEST_CLEAR_WIDGETS` という「実行する前に補完内容を消す widget のリスト」があります。この変数に <kbd>^M</kbd> に bind されている widget を登録してやればいいのです。

```shell:~/.zshrc
ZSH_AUTOSUGGEST_CLEAR_WIDGETS=(auto_bundle_exec_accept_line $ZSH_AUTOSUGGEST_CLEAR_WIDGETS)
```

[zplug](https://github.com/zplug/zplug) を使っている人は zsh-autosuggestions のロード後に変数の設定が行われるよう `hook-load` オプションを使いましょう [^1]。

```shell:~/.zshrc
zplug "zsh-users/zsh-autosuggestions", hook-load: "ZSH_AUTOSUGGEST_CLEAR_WIDGETS=(auto_bundle_exec_accept_line $ZSH_AUTOSUGGEST_CLEAR_WIDGETS)"

```

[^1]: qop さんのご指摘により hook-load` を使った記述に修正しました。
schemeで複合データを扱うには配列のパターンマッチングを用いるのが良い

#はじめに

大抵のプログラマはLISPが好きだと思うが、メインで使う人は少ない。その理由として、複合的なデータ（例えば座標とか）の扱いが挙げられるのではないだろうか。

LISPには一般的にクラスみたいな複合データのファーストオブジェクトがないので、配列で賄うこととなる。大抵の場合はdefine-structみたいなマクロが用意され、

	(define-struct point3d (x y z))

などと宣言し、

	(let [[p (point3d 1 2 3)]] ...)

などと値を生成する。ここまではいい。問題はその後で要素にアクセスする場合だ。

	(draw-dot (point2d-x p) (point2d-y p) (point2d-z p))

などといちいちアクセサにデータの名前が入る。俺はこれが嫌でたまらず、schemeはリスト処理のみに使うと決めて今までやってきた。

しかし先日散歩をしていたところ、突然ピコーンと閃いたのだ。haskell先生のcase文みたくパターンマッチングで要素にアクセスすればいいんじゃね？

	(mylet [[[x y z] (point3d 1 2 3)]]
	  (draw-dot x y z))

当初自分でマクロを書くつもりだったのだが、すでに同じことを誰かがやっているに違いないと思い探してみたところ、やっぱりありまちた。match-letとゆうのが。

#match-let

結構メジャーなマクロらしくいろんなschemeで採用されているようだが、俺が愛用するchicken schemeでは以下のようにモジュールを追加しなければならない。

> chicken-install matchable
> rlwrap csi -R matchable

話それるが、chicken schemeは目的の関数やマクロを使うのに何のモジュールが必要なのかいまいち分かりづらい気がする。チキンだから仕方ないのか。

match-letの使い方は簡単。

	(define (point3d x y z)
	  (vector 'point3d x y z))

などとコンストラクタがある時、

	(match-let [[#(_ x y z) (point3d 1 2 3)]]
	  (draw-dot x y z))

などとパターンマッチングできる。言わずもがなだが、アンダーバーは任意の要素にマッチする。値を読み飛ばすのに用いるのだ。

またパターンマッチングは入れ子にすることもできるのであって、

	(define (polygon3d p1 p2 p3)
	  (vector 'polygon3d p1 p2 p3))

	(match-let* [[p1 (point3d 1 2 3)]
	             [p2 (point3d 4 5 6)]
	             [p3 (point3d 7 8 9)]
	             [#(_ #(_ x1 y1 z1)
	                  #(_ x2 y2 z2)
	                  #(_ x3 y3 z3)) (polygon3d p1 p2 p3)]]
	  (draw-polygon x1 y1 z1 x2 y2 z2 x3 y3 z3))

うーんいいんじゃないかこれは？

いや、むしろすごくいい。というのもpythonやらrubyやらの動的型付け言語で複合データの要素にアクセスする時、ハッシュやらなんやらでシンボルの探索が行われるはずだからだ。肝の部分なので最適化されているにしても、若干のコストは免れ得ないだろう。上述のパターンマッチングではそれがない。ないと思う。

#match

もちろん普通のマッチングも用意されているのであって、

	(match (point3d 1 2 3)
	  (#('point3d x y z)
	   (draw-dot x y z))
	  (_ (error "ボケか糞が！")))

このようにこちらのマッチングでは最初の要素もチェックすべきであろう。

#おわりに

まあ、そんなわけで俺的にschemeは極めて望ましい動的型付けの関数型言語となった。特にchicken schemeはコンパイルができWindows/Mac/Unixのクロスプラットフォーム開発も可能なので、今後は積極的に使おうと思っている。

上述の内容は情報強者の皆さんにとっては周知のことなのかもしれないが、少なくとも国内のscheme入門サイトでは触れられていない。なので俺と同じ見逃しをしている人は多いんじゃないかと思い投稿してみた次第である。

いじょう
FileZillaでデフォルトのエディタを設定する方法

FileZillaを使っていて、バッチファイルなどをダブルクリックしてもエディタが開かないことがあり、とても不便でした。
すべてVSCodeで開くように設定したので、そのメモ

# 環境
Windows 10
FileZilla 3.31.0

#ダブルクリックの動作の設定
編集>設定を開き、インターフェイス>ファイル一覧でダブルクリック時の動作>ファイルをダブルクリックしたときの動作を表示/編集に修正

# デフォルトのエディタの設定
編集>設定を開き、ファイルの編集で既存のエディタでカスタムエディタを使用にチェックをし、VSコードを設定に修正

#ファイルの関連付け
~~これだけではtxtではきちんとVSCodeで開いてくれますが、rubyやバッチなどは開いてくれません。そこで拡張子ごとに設定します。
編集>設定で、ファイルの編集?ファイルの種類の関連付けで、以下のように拡張子ごとに設定します。~~
![image.png](https://qiita-image-store.s3.amazonaws.com/0/202761/27b4c75e-c3c5-ddad-480d-e497170e6b62.png)

(2018/04/19追記)
関連付けしなくてもデフォルトで設定できました。
編集>設定を開き、ファイルの編集で常にデフォルトのエディターを使用を選択でできました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/202761/1f98aa7c-ac4c-e59d-f9a4-4305da70cc79.png)