OmniAICreator/Qiita-1.07M huggingface dataset:
$rake db:migrate時にrake aborted! NoMethodError: undefined method `last_comment'が表示された時の解決方法



##エラーが出た状況

cloud9を使用し、Ruby on railsのアプリ開発をしているrails２か月目の初心者です。



マイグレーションを実行しようとしたところ、このようなエラーが出てしまいました。

```
$ rake db:migrate
rake aborted!
NoMethodError: undefined method `last_comment' for #<Rake::Application:xxxxxxxxxx>
/usr/local/rvm/gems/ruby-2.4.1/gems/rspec-core-3.1.7/lib/rspec/core/rake_task.rb:104:in `define'
/usr/local/rvm/gems/ruby-2.4.1/gems/rspec-core-3.1.7/lib/rspec/core/rake_task.rb:80:in `initialize'
/usr/local/rvm/gems/ruby-2.4.1/gems/rspec-rails-3.1.0/lib/rspec/rails/tasks/rspec.rake:11:in `new'
/usr/local/rvm/gems/ruby-2.4.1/gems/rspec-rails-3.1.0/lib/rspec/rails/tasks/rspec.rake:11:in `<top (required)>'
/usr/local/rvm/gems/ruby-2.4.1/gems/rspec-rails-3.1.0/lib/rspec-rails.rb:13:in `load'
/usr/local/rvm/gems/ruby-2.4.1/gems/rspec-rails-3.1.0/lib/rspec-rails.rb:13:in `block in <class:Railtie>'
/usr/local/rvm/gems/ruby-2.4.1/gems/railties-5.0.7/lib/rails/railtie.rb:239:in `instance_exec'
/usr/local/rvm/gems/ruby-2.4.1/gems/railties-5.0.7/lib/rails/railtie.rb:239:in `block in run_tasks_blocks'
/usr/local/rvm/gems/ruby-2.4.1/gems/railties-5.0.7/lib/rails/railtie.rb:247:in `each'
/usr/local/rvm/gems/ruby-2.4.1/gems/railties-5.0.7/lib/rails/railtie.rb:247:in `each_registered_block'
/usr/local/rvm/gems/ruby-2.4.1/gems/railties-5.0.7/lib/rails/railtie.rb:239:in `run_tasks_blocks'
/usr/local/rvm/gems/ruby-2.4.1/gems/railties-5.0.7/lib/rails/application.rb:442:in `block in run_tasks_blocks'
/usr/local/rvm/gems/ruby-2.4.1/gems/railties-5.0.7/lib/rails/engine/railties.rb:13:in `each'
/usr/local/rvm/gems/ruby-2.4.1/gems/railties-5.0.7/lib/rails/engine/railties.rb:13:in `each'
/usr/local/rvm/gems/ruby-2.4.1/gems/railties-5.0.7/lib/rails/application.rb:442:in `run_tasks_blocks'
/usr/local/rvm/gems/ruby-2.4.1/gems/railties-5.0.7/lib/rails/engine.rb:457:in `load_tasks'
/home/ec2-user/environment/kyounogohan/Rakefile:6:in `<top (required)>'
/usr/local/rvm/gems/ruby-2.4.1/gems/rake-12.3.1/exe/rake:27:in `<top (required)>'
/usr/local/rvm/gems/ruby-2.4.1/bin/ruby_executable_hooks:24:in `eval'
/usr/local/rvm/gems/ruby-2.4.1/bin/ruby_executable_hooks:24:in `<main>'
(See full trace by running task with --trace)
```




##解決方法

以下のサイトを参考にしました
[最初の RSpec テストが失敗する場合](https://www.oiax.jp/books/rails_kochiku_guide/first_rspec_example_failure.html)


Gemfileに以下のように追加する。

```Gemfile

（略）
gem 'rake', '< 11.0'
```

そのあと、ターミナルで以下を実行。

```ターミナル
$ bundle update rake
```

もう一度、マイグレーション。

```
$ rake db:migrate
== 20180907133239 CreateTags: migrating =======================================
-- create_table(:tags)
   -> 0.0123s
== 20180907133239 CreateTags: migrated (0.0131s) ==============================

== 20180907133339 CreatePostTagRelations: migrating ===========================
-- create_table(:post_tag_relations)
   -> 0.0328s
== 20180907133339 CreatePostTagRelations: migrated (0.0378s) ==================

Annotated (4): app/models/post_tag_relation.rb, spec/models/post_tag_relation_spec.rb, app/models/tag.rb, spec/models/tag_spec.rb
```

うまくいきましたー！サイトで教えてくださった方様様です。
GemfileにRakeを記述していないとああいうエラーが出るのでしょうか。
原因説明までできておりませんが、今日のエラーは以上です。
Rubyのresolvライブラリで `dig +short` を代替

ネームサーバーの動作確認をするのに [`dig` コマンド](https://ftp.isc.org/isc/bind/9.11.4/doc/arm/man.dig.html)を使って問い合わせを試していたが、Rubyでスクリプト化する際にコマンド呼び出しではなくRubyのライブラリでできないかと思い、方法を調べた。

`dig +short` のように結果のみでいいのならば、標準ライブラリの `resolv` で代替できそう。

```bash:bash
dig  @8.8.8.8  +short +time=1 +tries=3  google.co.jp. any
dig  @8.8.8.8  +short +time=1 +tries=3  google.co.jp.
dig  @8.8.8.8  +short +time=1 +tries=3  -x 8.8.4.4
```

↓

```ruby:ruby
require 'resolv'

Resolv::DNS.open(nameserver: "8.8.8.8") do |dns|   # ブロックなら DNS#close を自動でする
	dns.timeouts = [1, 1, 1]   # リトライ毎にタイムアウトを変えられる
	p dns.getresources("google.co.jp.", Resolv::DNS::Resource::IN::ANY)
	p dns.getaddresses("google.co.jp.")
	p dns.getnames("8.8.4.4")
	nil   # ブロックの戻り値、今回は明示的に空にしておく
end
```

結果を得るメソッドは、 resource, address, name それぞれに3種類ある。

* `getXXXs` は全ての結果を配列で返す（見つけられなければ空配列）
* `getXXX` は最初の結果のみを返す（見つけられなければ例外 `Resolv::ResolvError` 発生）
* `each_XXX` は全ての結果をイテレーションできる

参考：[Rubyリファレンスマニュアル resolvライブラリ](https://docs.ruby-lang.org/ja/latest/library/resolv.html)
再利用可能なページ読み込み？load()とajax()の違い

```js:javascript.js
$('div').load('other.html');
```
"other.html"というファイルを読み込むんだな。
とわかった人は飛ばしてください。

分からなかった人へ：~~上記の通りです。~~次へ進んでください。

#load()とは

任意のファイルを**HTMLコンテンツ**として取得＆出力することができるメソッド

※HTMLコンテンツ＝全てのWebページで再利用できるHTMLファイルのこと

##使用例（１）
```text:sample.txt
サンプルテキストです
```
上記のような~~つまらない~~テキストファイルを用意する。

```html:index.html
// 略
<body>
  <div></div>
  <script>
    $('div').load('sample.txt');
  </script>
</body>
```
そして上記のような~~つまらない~~空div要素のみのHTMLファイルを作る。

このHTMLファイルを読み込むと、div要素内に「サンプルテキストです」と表示される。

この「サンプルテキストです」がHTMLコンテンツである。
この方法で表示することで、好きな箇所で外部ファイルの中身を出力できる。

##使用例（２）

```html:list.html
<ul>
  <li>リスト１</li>
  <li>リスト2</li>
  <li>リスト3</li>
</ul>
```

上記のように~~見たら分かるような~~リスト要素のみのHTMLファイルを用意する。

```html:index.html
// 略
<body>
  <div></div>
  <script>
    $('div').load('list.html');
  </script>
</body>
```

そして上記のような~~つまらない~~空div要素のみのHTMLファイルを作る。

すると、空div要素の中にリスト要素が挿入される。
リスト要素をヘッダー要素にすれば、再利用可能なヘッダーコンテンツとなる。

#ajax()とは
説明するよりコードで解説。
以下の２つは同じ動作をします。

```js:javascript.js
$('div').load('other.html');
```

```js:javascript.js
.ajax({
  type: 'GET',
  url: 'other.html',
  success: function(data) {
    $('div').html(data);
  }
})
```

load()メソッドはHTMLファイルを読み込んで出力するだけの機能
loadメソッドの中身はajax()が動作しています

つまり、
load()メソッド ＝ ajax()メソッドの機能を限定的にした簡易版

##セレクタ指定、要素指定、function関数設定もできる
詳しくは以下のサイトで解説してくれている
> text jQuery入門】load()でHTMLを読み込む方法！
>> https://www.sejuku.net/blog/42555

・load()関数とは
・load()とajax()の違い
・再利用可能なページとは

これら３つが理解できればよし◎
お疲れ様でした。
RasPiのホスト名を変更したい

RasPiも同時に2台以上使いたい場合は、ホスト名がraspberryだけでは区別がつきません。
そこで、名前を変更しましょう。

##0.名前を変更するためには、2つのファイルを触らないといけないらしい
僕は、rpicluster00に変更します。

##1.まずはhostname
```
pi@raspbery:~ $ sudo vi /etc/hostname
```

1行目にraspberryと記述されていると思いますから、そこを変更します。

```
rpicluster00
```

保存して終了。再起動しないで。

##2.次にhosts

```
pi@raspbery:~ $ sudo vi /etc/hosts
```

127.0.1.1の後ろがraspberryになっていると思いますから、そこを変更します。

```
127.0.0.1       localhost
::1             localhost ip6-localhost ip6-loopback
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters

127.0.1.1       rpicluster00
```

ついでに（何のだ？）、他のRasPiの情報も追加したいなら

```
172.16.1.100    rpicluster00
172.16.1.101    rpicluster01
172.16.1.102    rpicluster02
172.16.1.103    rpicluster03
172.16.1.104    rpicluster04
172.16.1.105    rpicluster05
```

てな感じで足しときましょう。

で、再起動して、名前が変わっていればOK
RasPiでIPアドレスを固定したい

いつもは、ルーターからDHCPで適当にIPアドレスをもらって、用は足りますが、サーバーとして使いたい場合は、そうも言ってられません。
なので、固定IPアドレスにします。

Raspbianのjessieの場合

エディタで開いて

```
pi@raspberry:~ $ sudo vi /etc/dhcpcd.conf
```

最後の方にIPアドレスとデフォルトゲートウェイ、あと、必要ならDNSサーバーの情報を追加します。

```
interface eth0
static ip_address=172.16.1.100/16
static routers=172.16.0.1
static domain_name_servers=8.8.8.8
```

保存して再起動します。起動時のログに

```
My IP address is 172.16.1.100
```

と表示されればOK。心配ならifconfigでも確認しましょう。
PukiWiki を Markdown に変換して Heroku 上の Growi にデプロイした

# 経緯
Pukiwiki をデプロイしていた VM が突然死し，早急に Wiki を復旧する必要がありました．
組織内でオンプレからクラウドに移行する動きがあったこと，そもそも Pukiwiki ってどうなの？という話などから，試しに Growi で Wiki を立ち上げてみることにしました．

# Growi
Markdown で記述できるオープンソースの Wiki です．[Crowi](http://site.crowi.wiki/) から派生したプロジェクトで，日本人の方が開発しているようです．
https://growi.org/
ソースコードは Github 上に公開されています．
https://github.com/weseek/growi
試しに Github のページを開いたところ，[Heroku Button](https://jp.heroku.com/elements/buttons) を発見しました．当時の私は一刻も早く Wiki を移行させたかったので，とりあえず Heroku にデプロイしてみた次第です．

# Heroku
PaaS (Platform as a Service) の形態で提供されているクラウドサービスで，アプリケーションをプラットフォーム上にデプロイできます．
https://jp.heroku.com/

## 登録
アカウントを持っていなかったので，上記リンクから新規登録しました．基本的には無料で利用できますが，Heroku の醍醐味 (?) であるアドオンを使うにはクレジットカードの登録が必要です．
Growi は [mLab MongoDB](https://elements.heroku.com/addons/mongolab) と [Bonsai Elasticsearch](https://elements.heroku.com/addons/bonsai) という 2 つのアドオンを使用しています．
Heroku では各アドオンの利用に対しても課金されますが，今回は無料枠内で構築できました．

## デプロイ
[Github のページ](https://github.com/weseek/growi) で「Deploy to Heroku」をクリックするだけです．Heroku 上のアプリ名称等を入力していくだけで，ほぼ自動的にアプリをデプロイできます．

# PukiWiki からの移行
Wiki を 1 から作るのであれば，以上の手順で構築完了です．
私の場合は Pukiwiki のデータを移す必要があったので，参考にした記事等を載せていきます．


- [pukiwikiからCrowiに移行する](https://qiita.com/tokumoto/items/5e621b5fadb028566c3a)
- [PukiWiki の文書を Markdown に変換するワンライナー(一部 crowi-plus 仕様)](https://qiita.com/yuki-takei/items/152e20f4421333ae8fd9)

基本的には上記リンクの通りにできましたが，私の環境ではワンライナーのパーサだと不十分でした．実際に使用したコードは以下の通りです．
水平線や改行コードの処理を修正しています．

```
find wiki_mod/wiki -type f | xargs gsed -i -e 's/ \[#[0-9a-z]\+\]$//g' -e 's/^\*\*\*/###/g' -e 's/^\*\*/##/g' -e 's/^\*/#/g' -e 's/^.*----.*$/___/g' -e 's/^---/    -/g' -e 's/^--/  -/g' -e 's/^\(\s*\)-\([^ ]\)/\1- \2/g' -e 's/^\(\s*\)+\([^ ]\)/\1+ \2/g' -e 's/&br;/<br>/g' -e 's/#br//g' -e 's/^#pre{*/```/g' -e 's/^}}*/```/g' -e 's/~/  /g' -e 's/%%/~~/g' -e "s/^\/\/.*$//" -e "s/^\#lsx/`echo -ne '\u0024'`lsx()/g"
```

# おまけ
Growi について調べながら記事を書いていると，[GROWI.cloud](https://growi.cloud/) というサービスを発見しました．2018年8月27日からクローズドβテスターの募集を開始したようです．
CookieのセットとCookieを指定してリクエスト

# Cookieについて考える

javascriptのfetchAPIでCookieのセットの仕方を調べてもいいのが出てこなかったので生のテキストでセットする方法を調べました．

## サーバ側のCookieのセットの仕方
`SetCookie: "任意の名前" = 値; Max-Age=<non-zero-digit>`

## リクエスト時のCookieのセットの仕方
`Cookie: "任意の名前" = 値`

fetchAPIでの実装は以下のようになります

```
fetch("http://＊＊＊＊＊＊.com/*****", {
  method: 'GET',
  credentials: 'include',
  headers: new Headers({
    "Cookie": "hogehoge=fugafuga; Max-Age=1000 * 60 * 60 * 60 * 24 * 7",
  })
}).then(res => res.json())
.catch(error => console.error('Error:', error))
.then(response => this.setState({score: response.score}))
```

リクエスト時にもSetCookieを使っていたのでCookieはセットされてるのにサーバ側で取得できないという不思議な現象が起きました，，
ライブラリばかりに頼らずに，ネットワークの基礎(？)的な部分を理解してライブラリが何をしてくれているのかを理解するのも重要だと思いました！
iOS12 の プッシュ通知お試し受信機能 Provisional Authorization をいろいろ触ってみた


# iOS12からプッシュ通知の許諾ダイアログを出さずに、ユーザにお試しプッシュ通知を送れるようになった

「お試し」と言っているけれども、プッシュ通知自体は本物の通知で、違いは **受け取ったあとにこのまま購読し続けるかどうかのボタンが通知に付与される** というところです

# 先に結論

結論から言うと、ほとんどのアプリですぐに導入できますが
いくつか注意点が必要です


# 実装


コードはこんな感じでいける
`options` に `.provisional` を含めるだけ

```swift
var options: UNAuthorizationOptions
if #available(iOS 12.0, *) {
    options =  [.alert, .badge, .sound, .provisional]
} else {
    options =  [.alert, .badge, .sound]
}
        
UNUserNotificationCenter.current().requestAuthorization(options: options) { granted, error in
   if granted {       
        DispatchQueue.main.async {
            UIApplication.shared.registerForRemoteNotifications()
        }
    }
}
```

`.provisional` を含めてる場合、プッシュ許諾ダイアログなしで `granted` に `true`が入ってくる
`registerForRemoteNotifications()` でちゃんとデバイストークンが発行されるので、
既存の通知許諾をONにした後の処理が使い回せるだろう

追記:
ステータスが provisional のとき、
`UIApplication.shared.isRegisteredForRemoteNotifications` は `true` になる

# お試しプッシュ通知受信後

「お試し受信中」に受け取ったプッシュ通知は、
**バッジや音が無い状態で受信され、さらに通知センターでしか見ることができない**

ほとんどのユーザはお試しプッシュが届いてることに気づかないんじゃないかという気がする…
それであれば、アプリ側で明示的に許諾を出してやるほうがいいかも…

## お試しプッシュ通知についているボタン

お試し受信中に受け取ったプッシュ通知には　**プッシュ通知をこのまま受け取り続けるか**、
それとも**オフにするか**のボタンが存在する

プッシュ通知を受け取ることにする場合は、さらに

 - 目立つように配信してもらうか（ロック画面　通知センター　バナー全部出し　サウンドとバッジもあり）
 - 目立たないように配信してもらうか（通知センターのみ　かつ　サウンドとバッジはなし）

をユーザが選択できるようになっている


受け取るを選択した場合は、目立つ目立たないどちらも 
`authorizationStatus`は `authorized`（通知許諾ON状態）になる

# 注意点

前述したとおり、通知センターを見ない限りお試しプッシュが届いてる事に気づかないのが懸念
許諾ダイアログを出したほうがマシな可能性がある

また、自分たちのDBでデバイストークンを管理しているサービスは、
お試しプッシュを安易に導入するとDBに大量のデバイストークンがinsertされてしまうかもしれない
【Laravel】Laravelでよく使うroute()とview()とredirect()まとめ


画面遷移系の関数でちょくちょくこんがらがるのでまとめときます

例としてここでのルーティングは以下の通りです

```web.php
Route::resource('users', 'UsersController');
```

# route()

View側でURLを指定するときに使用



```html
<!-- 省略 -->
<a href="{{ route('users.edit', ['id' => $user->id]) }}">編集する</a>
<form method="POST" action="{{ route('users.destroy', ['id' => $user->id]) }}">
    {{ csrf_field() }}
    {{ method_field('DELETE') }}
    <button type="submit" onclick="return window.confirm('削除しますか？');">
        <span>削除する</span>
    </button>
</form>
<!-- 省略 -->
```

# view()

Controllerで特定のViewを**表示**させたいときに使用

```UsersController.php
    public function edit($id)
    {
        return view('user.edit', ['user' => User::find($id)]);
    }
```

表示させるときに変数を定義してViewに渡すことができる

```user/edit.blade.php
@if (!empty($user->name))
    {{ $user->name }}
@endif
```

# redirect()

Controllerで特定のページへ**リダイレクト**させたいときに使用

以下例

```UsersController.php
    public function destroy($id)
    {
        $user = User::find($id);

        // 処理やら

        if ($user->delete()) {
            return redirect('/top')->with('message', '削除しました。');
        }
        return redirect('/top')->with('message', 'エラー');
    }
```

`with()`を付けとくと遷移先でメッセージなどを表示させることができる

```index.blade.php
@if (Session::has('message'))
    <p>{{ session('message') }}</p>
@endif
```

ほかに`withInput()`とかもあります

# 参考
- [ルーティング 5.5 Laravel](https://readouble.com/laravel/5.5/ja/routing.html)
- [コントローラ 5.5 Laravel](https://readouble.com/laravel/5.5/ja/controllers.html)
- [ビュー 5.5 Laravel](https://readouble.com/laravel/5.5/ja/views.html)

# おわり

以下もどうぞ

- [【Laravel】わりとよく使うArtisanコマンド集](https://qiita.com/sola-msr/items/a09b857c5e7f7c88d01d)
- [【Laravel】DB登録値取得時のfind()、get()、first()の返り値早見表](https://qiita.com/sola-msr/items/fac931c72e1c46ae5f0f)
- [【Laravel】Viewのbladeの書き方](https://qiita.com/sola-msr/items/a128f4e0900f3541690c)
WindowsでJupyter notebookにJulia v1.0を追加してHello,Worldするまでのメモ

## 背景
Julia v1.0をJupyter notebookから使えるようにするまでちょっとてこずったのでそのメモ。

## 前提条件
* Windows 10 64bit
* Anaconda3(Jupyter notebook含む)はすでにインストールされた状態（Anaconda3をインストールしたときのメモは[こちら](https://qiita.com/SouTakenaka/items/9801f30c2fd1a378518d)）。

## 方法
#### Anaconda環境外にJuliaをインストールする
1-1. [Juliaの公式ページ](https://julialang.org/downloads/)にアクセスし、julia-1.0.0-win64.exeをダウンロードした。
1-2. `C:\Users\（ユーザ名）\Julia-1.0.0`にインストール。
1-3. ユーザ環境変数に変数名`PATH`、値`C:\Users\（ユーザ名）\Julia-1.0.0\bin`を追加。（しなくていい？）
1-4.ユーザ環境変数に
変数名：`JUPYTER`、
値：`C:\Users\（ユーザ名）\Anaconda3\Scripts\jupyter.exe`を追加

#### Juliaからnotebookをたちあげる
2-1. REPLを開いた。![julia_REPL.jpg](https://qiita-image-store.s3.amazonaws.com/0/253018/bf03e976-a554-6538-f6bd-e078914be5b1.jpeg)
2-2. import Pkgと入力
2-3. ]を押してパッケージモードへ（緑色→青色）
2-4. add IJuliaと入力
2-5. build IJuliaと入力
2-6. バックスペースを押し、パッケージモードから抜ける。
2-7. using IJuliaと入力。Ijuliaがプリコンパイルされる。
2-8. notebook()と入力→JupyterNotebookが開く。
2-9. 任意のディレクトリに移動
2-10. New▼からJulia1.0.0を選択し、新しいノートブックができる。
![julia_v1.jpg](https://qiita-image-store.s3.amazonaws.com/0/253018/268fc4e0-872f-225e-2d05-091642adbef9.jpeg)

13. print("Hello, World!)と入力し、Ctrl+Enterで実行。
![julia_v1_HelloWorld.jpg](https://qiita-image-store.s3.amazonaws.com/0/253018/447a065a-6314-0041-d4e6-f3ece571aec9.jpeg)


## 手こずったところ
### パッケージモードの存在
Julia v0.7以降ではパッケージモードが追加された。
julia>（緑色）のとき]を入力すると(v1.0) pkg>に変わる。これがパッケージモード。
パッケージモードはバックスペースで抜けられる。
julia> Pkg.add("IJulia")と(v1.0) pkg> add IJuliaは同じ操作。


### IJuliaのビルドでこける
build IJuliaしたとき、ERROR conda.core.link:_execute(502)みたいなのが出て、IJuliaのビルドが終わらないという問題。
色々調べて add Conda#masterしたり.Juliaファイル内を全部削除して入れ直してみたりしたけどダメだった。
ユーザ環境変数に変数名：`JUPYTER`、値：`C:\Users\（ユーザ名）\Anaconda3\Scripts\jupyter.exe`を追加したらビルドできるようになった。

## 参考文献
Julia 1.0 を Jupyter Notebook から使う
ystt
https://ystt.hatenablog.com/entry/2018/08/11/141132

WindowsへのJulia言語のインストール
黒木玄
http://nbviewer.jupyter.org/gist/genkuroki/81de23edcae631a995e19a2ecf946a4f?flush_cache=true#Anaconda3%E3%81%A8Julia-v1.0%E3%81%AE%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B-(2018-09-05%E3%81%AB%E8%BF%BD%E5%8A%A0)
JUnitのMockでany使ったらInvalidUseOfMatchersExceptionが出た

# はじめに
JUnitのMockitoでMatchersのany()を使ったらInvalidUseOfMatchersExceptionが出ました。
その解決法をまとめます。

# 症状

こんな感じのテストコードを書いてみました。

```java
@Test
public void testDoSomething() {
    Hoge hoge = mock(Hoge.class)
    when(hoge.doSomething(any(), "bar")).thenReturn(true);
}
```

`hoge.doSomething()`の第一引数は独自定義したクラスだったので、`org.mockito.Matchers.any()`を入れてます。
第二引数はString型で、特定の文字列を入れてます。

この状態でテストを実行してみると、こんなExceptionが発生しました。

```console
org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
5 matchers expected, 3 recorded:
-> at hogehoge
-> at hogehoge
-> at hogehoge

This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
    //correct:
    someMethod(anyObject(), eq("String by matcher"));

For more info see javadoc for Matchers class.
```

# 分析
> When using matchers, all arguments have to be provided by matchers.

このエラーメッセージを読む限り、どうやらすべての引数をmatchers形式にする必要があるようです。
String型の引数の場合、`eq()`を使えば良さそうです。


# 解決法

```java
when(hoge.doSomething(any(), "bar")).thenReturn(true);
```

上記のコードを以下のように変えてみたらExceptionが発生しなくなりました。

```java
when(hoge.doSomething(any(), eq("bar"))).thenReturn(true);
```

# さいごに
解決法まで詳しく書いてある丁寧なエラーメッセージで助かりました。
Matchers良いですね。
Scalaのscala.util.TryでJavaのtry-catch-finallyを表現する

Javaの`try-catch-finally`は致命的なエラー(FatalError)は捕捉しませんが、
Scalaの`try-catch-finally`は致命的なエラーも捕捉してしまいます。
致命的な例外として有名なのは`OutOfMemoryError`などがあり、このような致命的な例外はプログラム中で捕捉すべきではありません。

```scala
scala> try {
     |   throw new StackOverflowError
     | } catch {
     |   case e: Throwable => println("error")
     | }
error
```

そこで、Scalaでは`try-catch-finally`ではなく、`scala.util.Try`を使って例外を捕捉する方法が一般的（？）になっています。
`scala.util.Try`は、Javaの`try-catch-finally`と同様に致命的ではないエラー（NonFatalError）しかキャッチしません。

```scala
scala> Try(throw new StackOverflowError) recover {
     |   case e: Throwable => println("error")
     | }
java.lang.StackOverflowError
  at .$anonfun$res13$1(<console>:13)
  at scala.util.Try$.apply(Try.scala:209)
  ... 38 elided
```

でも、`scala.util.Try`は、例外がスローされた時には`Failure`になってしまい、最後に何かを実行する`finally`のような仕組みはありません。 Scalaでも`finally`したい。そんな時があると思います。

そんな時には`scala.util.control.Exception.ultimately`を使うという手段があります。例外が発生してもしなくても最後に実行する処理を渡すことで`finally`を実現可能です。

```scala
scala> Try {
     |   ultimately {
     |     println("finally !")
     |   } {
     |     println("do something")
     |     throw new Exception
     |     println("no execute")
     |   }
     | }
do something
finally !
res: scala.util.Try[Unit] = Failure(java.lang.Exception)
```

このような書き方であれば、致命的なエラーに関しては無視し、致命的ではないエラーのみを補足することができます。
もちろん`finally`を使う必要がないなら`ultimately`も必要ありません。

## 参考文献

scala.util.control.Exceptionに関する日本語の記事は2つぐらいしかないです。

* http://seratch.hatenablog.jp/entry/20111126/1322309305
* http://www.mwsoft.jp/programming/scala/scala_try.html

## 追記

コメントいただきましたが、Scalaの`try-catch-finally`でも、
`catch`で`NonFatal`を用いてパターンマッチを行うと、致命的ではないものだけを補足できます。

[NonFatalの例外 - scala_text](https://dwango.github.io/scala_text/error-handling.html#nonfatal%E3%81%AE%E4%BE%8B%E5%A4%96)
Go言語でTwitterAPIを利用する(anacondaの利用)

# 前提
- TwitterAPIを利用するために、Twitterアプリケーションの登録(APIキーとアクセストークンの発行)を行う必要があります
- Golangはインストール済み
    - [GolangのインストールからHelloWorldまで](https://qiita.com/dahiyu/items/510541e72259b83956cc)
- 環境変数はgodotenvを利用しています
    - [godotenvで環境変数をファイルから読み込む-Golang](https://qiita.com/dahiyu/items/bae08e2900022e5a2d56)

# anacondaをインストール

```shell-session
$ go get github.com/ChimeraCoder/anaconda
```

# Twitterで「golang」で検索した結果を取得してみる

```go:search.go
package main

import (
	"fmt"
	"log"
	"net/url"
	"os"

	"github.com/ChimeraCoder/anaconda"
	"github.com/joho/godotenv"
)

func loadEnv() {
	err := godotenv.Load()
	if err != nil {
		log.Fatal("Error loading .env file")
	}
}

func getTwitterApi() *anaconda.TwitterApi {
	anaconda.SetConsumerKey(os.Getenv("CONSUMER_KEY"))
	anaconda.SetConsumerSecret(os.Getenv("CONSUMER_SECRET"))
	return anaconda.NewTwitterApi(os.Getenv("ACCESS_TOKEN"), os.Getenv("ACCESS_TOKEN_SECRET"))
}

func main() {
	loadEnv()

	api := getTwitterApi()

	v := url.Values{}
	v.Set("count", "30")

	searchResult, _ := api.GetSearch("golang", v)
	for _, tweet := range searchResult.Statuses {
		fmt.Println(tweet.Text)
	}
}
```

# 終わりに
記事では検索しかしませんが、ドキュメント読むといろいろなことができる模様。

・ドキュメント
https://godoc.org/github.com/ChimeraCoder/anaconda
【PHP】サーバーのホスト名によって実行する処理を切り分ける


# `$_SERVER['SERVER_ADDR']` が使えない

`$_SERVER['SERVER_ADDR']`を出力しようとするとエラーがでてしまう。
（サーバーの設定かな？わからん）

# 代わりにサーバーのホスト名で判定する

以下ソース

```php
// 1号機以外は処理を実行しない
if (gethostname() === 'server_one') {
    // 1号機のみ実行する処理
}
```

# 参考

[PHP: gethostname - Manual](http://php.net/manual/ja/function.gethostname.php)
【たのしくおしごと】グランドスラムチャンネル on Slack【第一回】

# 第一回
だいいっかい
## たのしくおしごととは
毎日のおしごとがほんの少しだけ楽しくなるようなちょっとした工夫を紹介していく記事である。
バカみたいなこともあれば結構いいんじゃね？ってのも書いていくつもりである。
色んな人がこのタグでこのシリーズを投稿してくれるようになれば、塵も積もれば山となるですごくたのしいおしごとになるのではないかと思っている。

##グランドスラムチャンネル
早速、記念すべきたのしくおしごとシリーズ第一回として、ワタクシの実践している中で最高レベルのほんのちょっとした工夫を紹介する。

### やること
1. Slackでも何でもいいが、組織のみんなが自由に見たり書いたりできるところにグランドスラムチャンネルを作る。
2. 月曜日から木曜日までは残業なしで帰れる日の帰り際に「シングル！」と投稿する。
※この際、月曜から水曜までシングルが続いている状態で木曜にも残業なしの場合は「ウノ！」と投稿する。
3. 金曜日はもちろん高めに打ちごろの棒球が来るので、残業なしの場合はホームランとなる。
しかし、残業してしまうとスリーアウトチェンジとなる。
4. 金曜日の帰り際に投稿する内容は以下である。

| 成績 | 書込み例 |
|:-:|:-:|
| ウノからの満塁ホームラン | グランドスラム達成！ |
| 満塁ホームラン | 満塁ホームラン！！！！ |
| 3ランホームラン | 3ランホームラン！！！ |
| 2ランホームラン | 2ランホームラン！！ |
| ソロホームラン | ソロホームラン！ |
| ウノからのチェンジ | 残塁グランドスラム達成！ |
| 残塁ありの通常のチェンジ | X者残塁！ |
| 残塁なしのチェンジ | 三者凡退うおお |

※月末には月間の打率を算出して競ってみてもいいかもしれない。

###これを続けた結果
なんか楽しくなってきた！！
まさにウディヤナバンダ！！（ヨガ）
まぁコンセプトが「たのしくおしごと」だし、このくらいの成果で十分なのかなぁと。

##あとがき
正直野球じゃなくても何でもいいんだけども。
むしろ週5日なのに野球にしてしまったせいで満塁ホームランとグランドスラムを分ける羽目になっている。
ホントに余裕がなくなってる時ってこういうことする余裕もなくなるので。
残業してもこういう書き込み見るとちょっとほんわかできるかなぁと。
帰り際に何か書くって結構効果的なことなんじゃないかと思う。
各人の稼働の状況が皆でなんとなくつかめるというチーミング的なメリットもある。
みんなの実践している（してなくても）こういうホンワカできるの知りたいなぁと思っている。
こんなところで今日は。せーのっ！サハスラーラ！:eye:
requests-htmlのuser-agentを確認してみる

動的なWEBページをスクレイピングしたいときに超便利なライブラリ[Requests-HTML](https://html.python-requests.org/)

JavaScriptを実行しないとスクレイピングできないWEBページでもHeadlessChromeとseleniumを用意する必要はありません

またrequests-htmlはデフォルトでuser-agentにブラウザの情報を設定してくれます

今回はその確認です

```python
In [1]: import requests

In [2]: from requests_html import HTMLSession

In [3]: session = HTMLSession()

In [4]: session.get('http://httpbin.org/user-agent').text
Out[4]: '{\n  "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8"\n}\n'

In [5]: requests.get('http://httpbin.org/user-agent').text
Out[5]: '{\n  "user-agent": "python-requests/2.18.4"\n}\n'
```

safariが設定されているみたいですね。ちなみに実行環境はwindows10です。
processing(java)でインスタンスからメソッドを名前検索して実行

面白いので残しておく

```processing:test.pde
import java.lang.reflect.*;
void setup(){
  Test test=new Test();
}

class Test{
  Test(){
    try{
      this.getClass().getMethod("test").invoke(this);
    }catch(NoSuchMethodException | e){
      println(e);
    }catch(IllegalAccessException e){
      println(e);
    }catch(InvocationTargetException e){
      println(e);
    }
  }
  void test(){
    println("test");
  }
}
```

javaでも同様に
Web3.pyでエラー: ModuleNotFoundError: No module named 'eth_utils.toolz'

# 現象
Web3.pyで何ぞするときに標題のようなエラーが発生することがあります。

```bash
ModuleNotFoundError: No module named 'eth_utils.toolz'
```

ライブラリが不足しているのかと思い`pip install -r requirements.txt` を叩いてもすでに入っている旨のログが出力されるだけ。

# 対応
そんな時は、基本ですが入っているeth系のライブラリをすべて削除して再度入れ直してみましょう。

```bash
rm -fr /Users/xxxx/.pyenv/versions/3.6.1/lib/python3.6/site-packages/eth_*
pip install -r requirements.txt
```
授業 : PC基礎１

#初めに
初めてQiitaに投稿します。
Markdown表記の勉強を兼ねて、学校の内容の復習と記録の為に使っていきます。

 ---
#SI接頭辞


０以下　　　　　　　　　　　　　　０以上
![SI.png](https://qiita-image-store.s3.amazonaws.com/0/287907/981a81da-95f3-81da-8a29-abb93d65ad26.png)

どこにでもある表の形ですが一応。
ケルビンの「K」と分けるためにキロの「k」は小文字とのことでした。
PCのことを話す前にここから始まりました。

---
# コンピュータの5大要素

【演算装置、制御装置】CPU
【記憶装置】メモリ、HDD
【入力装置】キーボード、マウス
【出力装置】ディスプレイ、プリンタ

- CPU=中央演算処理装置=Central Processing Unit
周辺装置の命令は「バス」を通して行われる。
命令は「機械語（マシン語）」として4~64ビットでやり取りが行われる。

##記憶装置  

1. 主記憶装置（メインメモリ）
各種処理するデータを一時的に保存しておく。
高速処理が可能で容量が小さい。
  - ROM=Read Only Memory : 不揮発性メモリ  
電源を切っても内部に保存されているデータは消えない。  
  - RAM=Random Access Memory : 揮発性メモリ  
電源を切ると内部に保存されているデータが消える。
     - DRAM(低速・大容量) : コンデンサ  
     メインメモリに使用される。
     - SRAM(高速・低用量) : 半導体、フリップフロップ回路  
     CPU内のキャッシュメモリに使用される。

2. 二次記憶装置
半永久的にデータを保存しておくことができる。
転送処理が低速だが、容量が大きい。
HDDやSSD、USBメモリ、各種メディアディスクがこれにあたる。




---
Facebook Graph API 用の無期限のアクセストークンを生成する

Facebook Graph API を叩くプログラムを開発するために、
無期限のアクセストークンを生成するスクリプトを書いた。

[Never Expiring Facebook Long Lived Access Token, Facebook Graph API](https://sujipthapa.co/blog/generating-never-expiring-facebook-page-access-token) でやっている内容と同等だと思う。

最初のアクセストークンは https://developers.facebook.com/tools/explorer から取得でき
期限の確認は https://developers.facebook.com/tools/debug/accesstoken/ からできる

```js:none_expired_token.js
(async () => {
  const axios = require('axios')


  const config = {
    redirect_uri: 'https://..../callback',
    client_id: '978620.....',
    client_secret: 'f50fcd29bb66.............',
  }

  // Usage
  // $ node none_expired_token.js $FB_ACCESS_TOKEN
  //
  // $FB_ACCESS_TOKEN as User Access Token from
  // https://developers.facebook.com/tools/explorer
  
  const fb_exchange_token = process.argv[2]

  // main
  const client = axios.create({
    baseURL: 'https://graph.facebook.com',
  })
  let response = null
  response = await client.post(`/oauth/access_token`, {
    redirect_uri: config.redirect_uri,
    grant_type: 'fb_exchange_token',
    client_id: config.client_id,
    client_secret: config.client_secret,
    fb_exchange_token,
  }).catch(e => {
    const message = e.response.data.error
    console.error(message)
  })

  const access_token = response.data.access_token

  response = await client
      .get(`/me/accounts`, {
        headers: {
          'Authorization': `Bearer ${access_token}`
        },
      })
      .catch(e => {
        const message = e.response.data.error
        console.error(message)
      })

  response.data.data.forEach(data => {
    console.log(data)
  })
})()

```

### おまけ: Koala(Ruby)版
`OAuth#exchange_access_token_info` というメソッドが生えてる。

```ruby
oauth = Koala::Facebook::OAuth.new(app_id, secret, callback_url)
result = oauth.exchange_access_token_info(oauth_token)
source_access_token = result['access_token']

graph = Koala::Facebook::API.new(source_access_token)
accounts = graph.get_object("me/accounts")

puts accounts
```
Babel 6 + TS 環境に Stylelint を雑に入れると Jest が通らない

先日 Babel の `v7.0.0` がついに [正式リリース](https://github.com/babel/babel/releases) されましたが、今自分がやっているプロジェクトでは訳あってもう少し 6 系を使う予定です。
そんな折、軽率に node_modules ディレクトリを削除して作り直したら Jest が通らなくなってしまい困ったので、おおまかな原因と解決方法をメモします。

## 前提

- JavaScript と TypeScript で開発をしている
- JS のトランスパイルには Babel 6 を使っている
- Stylelint も使っている
- Jest も使っている
- `ts-jest@23.1.4` を使っている

## 起きたこと

Jest が以下のようなエラーを吐くようになり、 TypeScript のテストをパス出来なくなってしまった。

```sh
 FAIL  path/to/test.spec.ts
  ● Test suite failed to run

    TypeError: Cannot read property 'bindings' of null

      at Scope.moveBindingTo (node_modules/@babel/core/node_modules/@babel/traverse/lib/scope/index.js:867:13)
      at BlockScoping.updateScopeInfo (node_modules/babel-plugin-transform-es2015-block-scoping/lib/index.js:364:17)
      at BlockScoping.run (node_modules/babel-plugin-transform-es2015-block-scoping/lib/index.js:330:12)
      at PluginPass.BlockStatementSwitchStatementProgram (node_modules/babel-plugin-transform-es2015-block-scoping/lib/index.js:70:24)
      at newFn (node_modules/@babel/core/node_modules/@babel/traverse/lib/visitors.js:193:21)
      at NodePath._call (node_modules/@babel/core/node_modules/@babel/traverse/lib/path/context.js:53:20)
      at NodePath.call (node_modules/@babel/core/node_modules/@babel/traverse/lib/path/context.js:40:17)
      at NodePath.visit (node_modules/@babel/core/node_modules/@babel/traverse/lib/path/context.js:88:12)
      at TraversalContext.visitQueue (node_modules/@babel/core/node_modules/@babel/traverse/lib/context.js:118:16)
      at TraversalContext.visitSingle (node_modules/@babel/core/node_modules/@babel/traverse/lib/context.js:90:19)
```

> node_modules/@babel/core

:thinking_face:

## 原因

- `stylelint` をバージョン固定せずにインストールしたことで `stylelint@9.5.0` がインストールされた。
- `stylelint@9.5.0` の依存パッケージである `postcss-jsx@0.33.0` の依存関係により Babel 7 (`@babel/core`) がインストールされてしまった。
    - 6系と7系はディレクトリが違うので、トップレベルの `node_modules` で同時に存在できる。
- Jest (`ts-jest@23.1.4`) は Babel の 6 でも 7 でも動くものの、7 があれあば先にそちらを参照する。
    - https://github.com/kulshekhar/ts-jest/blob/v23.1.4/src/utils/imports.ts#L9

ここから先は追えてないんですが `.babelrc` なども Babel 6 を想定した記述になっているので、そこらへんでコケているんじゃないかと思います。

## 対応

とりあえずの対応として、Babel 7 がインストールされない Stylelint のバージョンを指定しました。
`stylelint@9.4.0` は `postcss-jsx` に依存しておらず Babel 7 は入ってこないので、これを採用しました。

## 今後

`ts-jest` のこの見境ないバベり問題は `ts-jest@23.10.1` で対応されるっぽいです :raised_hands:
[roadmap to next version \(probably \`23\.10\.1\`\) · Issue \#697 · kulshekhar/ts\-jest](https://github.com/kulshekhar/ts-jest/issues/697)

## 思ったこと (追記)

これって `package-lock.json` まで消さなければ起こらなかった問題では…？
godotenvで環境変数をファイルから読み込む-Golang

# godotenvをインストール

```shell-session
$ go get github.com/joho/godotenv
```

# .envファイルを作成

```:.env
USER_NAME=root
PASSWORD=password
```

# .envを利用する

```go:dotenvtest.go
package main

import (
	"fmt"
	"log"
	"os"

	"github.com/joho/godotenv"
)

func main() {
	err := godotenv.Load()
	if err != nil {
		log.Fatal("Error loading .env file")
	}

	fmt.Println(os.Getenv("USER_NAME"))
	fmt.Println(os.Getenv("PASSWORD"))
}
```

# 実行

```shell-session
$ go run dotenvtest.go
root
password
```
LB配下のサーバ(Apache)で複数サイトに別々の設定(Basic認証とIP制限)したい

#やりたいこと
- LB配下のサーバ内ApacheでBasic認証とIP制限をする
- 同一サーバ内に同じドキュメントルートでフロント画面と管理画面がある
    - フロント画面(front-website.com)はIP制限なし、Basic認証あり
    - 管理画面(backend-website.com)はIP制限あり、Basic認証なし

#構成
- サーバにはフロント画面(front-website.com)と管理画面(backend-website.com)がある
- LB1台、サーバ1台
- CentOS7
- Apache2.4
- AWS

#実際に設定した内容　※該当箇所のみ抜粋
- allow_ip1~allow_ip3のIPアドレスが管理画面(backend-website.com)

```
<VirtualHost *:80>
    ServerName front-website.com
    DocumentRoot "/var/www/html"

    <Directory "/var/www/html">
        Options FollowSymLinks ExecCGI Includes
        DirectoryIndex index.html index.php
        AllowOverride All
        EnableMMAP Off
        EnableSendfile Off
    </Directory>

    <Location "/">
##★Basic認証設定★
        AuthType Basic
        AuthUserFile /etc/httpd/conf/.htpasswd
        AuthGroupFile /dev/null
        AuthName "Basic Auth"
        Require valid-user

##★ヘルスチェックからBasic認証を外す★
        Satisfy Any　
        SetEnvIf Request_URI "/health.html" healthcheck
        Order Deny,Allow
        Deny from all granted
        Allow from env=healthcheck
    </Location>
</VirtualHost>

<VirtualHost *:80>　
    ServerName backend-website.com
    DocumentRoot "/var/www/html"

    <Directory "/var/www/html">
        Options FollowSymLinks ExecCGI Includes
        DirectoryIndex index.html index.php
        AllowOverride All
        EnableMMAP Off
        EnableSendfile Off
    </Directory>

    <Location "/">
      Require all denied

      Satisfy Any
      SetEnvIf X-Forwarded-For "123\.123\.123\.123.*" allow_ip1　★許可するIPアドレス1
      SetEnvIf X-Forwarded-For "456\.456\.456\.456.*" allow_ip2　★許可するIPアドレス2
      SetEnvIf X-Forwarded-For "789\.789\.789\.789.*" allow_ip3　★許可するIPアドレス3
      Order Deny,Allow
      Deny from all
      Allow from env=allow_ip1
      Allow from env=allow_ip2
      Allow from env=allow_ip3
    </Location>
</VirtualHost>
```

#つまづいたところ
##ApacheでのIP制限がうまくいかない問題
###原因
- ApacheがリモートIPアドレスを拾うことが出来ていなかったため設定が反映されなかった。
    - 以下の設定だとアクセス時のIPはLBのIPをApacheが判断してしまい、allow_ipでアクセスしてもアクセス不可能でした。

####もともと設定していた悪い例
```
<VirtualHost *:80>
    ServerName backend-website.com
    DocumentRoot "/var/www/html"

    <Directory "/var/www/html">
        Options FollowSymLinks ExecCGI Includes
        DirectoryIndex index.html index.php
        AllowOverride All
        EnableMMAP Off
        EnableSendfile Off
    </Directory>

    <Location "/">
      Require all denied

      Require ip 123.123.123.123 allow_ip1　★許可するIPアドレス1
      Require ip 456.456.456.456 allow_ip2　★許可するIPアドレス2
      Require ip 789.789.789.789 allow_ip3　★許可するIPアドレス3
    </Location>
</VirtualHost>
```
kintoneのテーブルをルックアップしてみた

# はじめに

kintoneのテーブルは標準機能ではルックアップでもってくることはできません（；＾ν＾）ぐぬぬ…
でもテーブルもごそっと持ってきたい時があるんです！！！

なので kintone REST API を使って疑似ルックアップ拡張してみました。

# 完成イメージ

![table_lookup.gif](https://qiita-image-store.s3.amazonaws.com/0/153051/67f364ff-bbe5-b0b2-3a6d-89e5316ba238.gif)
※ルックアップクリアがなんか残ってるけど、、(ﾟεﾟ)ｷﾆｼﾅｲ!! 
※↑ 後ほど理由を説明します

# 仕組み

ルックアップをした時、つまり**「ルックアップフィールドが変わった時」**か**「ルックアップの取得ボタンを押した時」**っていうイベントがあればなんの造作もないのですが、
どちらもイベントが用意されていないので、「ルックアップで持ってきたフィールドのチェンジイベント」で処理を発火させています🔥🔥


ここのイベントがほしいんじゃー！！(ないものねだり)
![2018-09-05_18h47_34.png](https://qiita-image-store.s3.amazonaws.com/0/153051/a308a782-6e26-aef4-87a3-5f543797b4ce.png)

ルックアップ元(マスタアプリ)のアプリIDを取得するAPIはあるので、ルックアップの標準機能でどのレコードIDからルックアップしてきてるか取得してREST APIのGETを実行しています。
※ そしてこの「レコードID格納用フィールド」のチェンジイベントで🔥しています

# kintoneアプリ

## フィールド構成

|フィールド|フィールドコード|用途
|---|---|---|
|ルックアップ|Lookup|ルックアップするため|
|数値|Number|ルックアップ元のレコードIDを格納|
|テーブル|Table|もってきたいテーブル|

※ **テーブルの構成、フィールドコードはルックアップ元/先で同じ** にしてください。あとで楽です。

その他必要なフィールドがあれば自由に配置してください。

## フィールド配置

配置が地味に大事だったりします！

ルックアップで持ってくるフィールドは上から(左上)から順番に取得するっぽくて、
レコードIDを格納するフィールドを上に持ってくるとちょっとバグります。

change イベントを紐づけている `レコードIDフィールド` に先に値が入ってしまうのでカスタマイズが動いてしまい、他のフィールドには値が入らないのです。
-> 再度、取得ボタンを押せば、他のフィールドにも値が入ります。

![table_lookup2.gif](https://qiita-image-store.s3.amazonaws.com/0/153051/c2a0dad8-ce2d-8067-385a-0996d5ff90ab.gif)

コード内にある kintone.app.record.set() が原因な気がしますね～(勘)


なのでチェンジイベントさせているレコードIDフィールドを一番下に持ってくるとうまいことできるようになります。

![table_lookup3.gif](https://qiita-image-store.s3.amazonaws.com/0/153051/6b3087d8-c4b6-67a4-d404-25dab8ffad2e.gif)

※ルックアップクリアが残るやつもなんとかなってる

# コード

[GitHub](https://github.com/RyBB/kintoneCustomize/tree/master/Tablelookup)に置いてあります。

```javascript
(function() {
  'use strict';
  const events = [
    'app.record.create.change.Number',
    'app.record.edit.change.Number',
  ];
  kintone.events.on(events, function(event) {
    const targetAppId = kintone.app.getLookupTargetAppId('Lookup');
    const targetRecordId = event.record['Number'].value;

    // ルックアップクリアをしたらテーブルを空にする
    if (!targetRecordId) {
      event.record['Table'].value = [];
      return event;
    }

    const body = {
      app: targetAppId,
      id: targetRecordId,
    };
    kintone.api(kintone.api.url('/k/v1/record', true), 'GET', body, function(resp) {
      event.record['Table'].value = resp.record['Table'].value;

      // サブテーブルを編集不可にする場合
      event.record['Table'].value.forEach(function(obj) {
        Object.keys(obj.value).forEach(function(params) {
          obj.value[params].disabled = true;
        });
      });

      kintone.app.record.set(event);
    }, function(err) {
      window.alert('REST APIでエラーが発生しました');
    });
  });
})();
```
ルックアップクリアさせたらテーブルを空にする処理だったり、サブテーブルを編集不可にしたりしてます。

また、テーブルの構成やフィールドコードを合わせることで、

```javascript
event.record['Table'].value = resp.record['Table'].value
```

でテーブルがごそっと持ってこれます。あら楽ちん

# おわりに

簡単なカスタマイズでもなるべくQiitaにあげようと思い作ってみました。
テーブルのルックアップは地味にニーズあるのでいつか標準対応してくれるといいな～
(そうなったらこのカスタマイズはお蔵ですけどね笑)

kintoneのカスタマイズで困ったことがあれば [cybozu developer network](https://developer.cybozu.io/hc/ja) のコミュニティで質問してみると良いですよ～！

それでは！≧(+･` ཀ･´)≦
fastlaneでextensionを含むアプリをresignする

# 問題

fastlaneは一度署名したipaを別の証明書に変えて再署名（＝resign）する機能がある[^1]。

しかし、この機能はアプリ本体のbundle idを変更してくれるけど、extensionのbundle idを変更してくれない。

[^1]: [resign - fastlane docs](https://docs.fastlane.tools/actions/resign/)

# 解決

extensionのbundle idを手動で変更できる。例えば、Notification Service Extensionの場合は、下記の手順で変更できる：

- ipaをどこかにunzipする
- plutilを使って、extensionのbundle idのみを変更する

```sh
plutil -replace CFBundleIdentifier -string new.bundle.id.for.extension Payload/FOO.app/PlugIns/NotificationService.appex/Info.plist
```

- 変更後のファイルツリーをzipして`.ipa`にリネーム

こうすれば、fastlaneで変更後のextensionに対して再署名を行うので、問題が解決する。
CentOSで鍵認証しようとがんばっても `Permission denied` となるあなたへ


# 最初に

## CentOSのお話です

鍵認証でいくら試しても、何度も権限周りを見直しても下記のように `Permission denied` と言われて心が折れたあなたへ。

```
deploy@hostname: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
```

# TL;DR

以下の条件に当てはまる場合はSELinuxを無効にして試してみてください

- 権限まわりはモニタに穴が空くほど見直した
- SSHでログインしようとしているユーザのホームディレクトリが、/home配下以外
- SELinuxが有効

# `Permission denied` は、権限の問題だ

本来 `Permission denied` であればほぼサーバ／クライアントの鍵関連の権限が問題です。 
Qiitaでもこれまで何度も記事になっているので、ぐぐってください（他力本願）

# それでもいくら権限周りを確認しても間違いはないよ…

もしかして、下記の条件に当てはまりませんか？もしそうならここが終着点です🐳

- SSHでログインしようとしているユーザのホームディレクトリが、/home配下以外
- SELinuxが有効

ええ、SELinuxのしわさです👿

# 問題切り分けのためにとりあえずの対応

SELinuxを無効にしてください。これでログインできるようになると思います。多分。
💭ただ、`/var/log/audit/audit.log` にそれっぽいログが見つからなかったんだよなぁ…

```
sudo setenforce 0
```

# 何が問題だったのか？

そもそもの原因はユーザのホームディレクトリを `/home` ではなく既存の別のディレクトリに配置したこと。SELinuxはディレクトリ毎に専用のラベルをもっています。
以下の `home_root_t` とか `user_home_dir_t` が今回ハマった箇所。

```
# ls -laZ /home
drwxr-xr-x. root    root    system_u:object_r:home_root_t:s0 .
dr-xr-xr-x. root    root    system_u:object_r:root_t:s0      ..
drwx------. vagrant vagrant unconfined_u:object_r:user_home_dir_t:s0 vagrant
```
もしホームディレクトリを別のところに移す場合、上記のようなラベルを張り直さないといけないのですが、新規ディレクトリならまだしも既存のディレクトリ（たとえば `var` 等）の場合は用途を考えると張り直すことができない場合も😇

# 最後に

SELinuxは厄介なものですが、基本セキュリティを守るものです。ホームディレクトリ配下をWeb公開したりとか、今回のようにホームディレクトリを既存ディレクトリ配下にしてしまうとか、セキュリティリスクが高いものに対してきちんと守ってくれます。

ただ、とにかく存在を忘れやすいのと、ググると大体 `SELinuxを無効に` とあってなかなか理解が深まらないものですよね。いつか時間をかけてきちんと理解できたらいいなーと思いつつ。
Node-REDをIPv6アドレスで接続できるようにして、Windows10 1803(mDNSサポート)のWebブラウザからhoge.localで接続できるようにする

# はじめに
Node-RED v0.18.7 時点でのデフォルトでは、WebブラウザからNode-REDへIPv6なURL＊で接続することができません。もちろん、Node-REDの設定を変更すればIPv6なURLでもアクセス可能です。

＊ IPv6なURLの例）https://[xxxx::xxxx:xxxx:...]:1880
＊ IPv4          https://192.168.x.x:1880

ところで、Windows10は、~~悪名高き~~ Windows10 2018 Spring Update(1803)パッチを当てることでmDNS＊が標準サポートされるようになりました。
＊ いままでは、Apple社のBonjourをWindowsにインストールして実現していました。

これで、ローカルネットワーク上のラズパイにWindowsからSSHやVNCやWebで接続する際＊、IPアドレスが何かを調べる必要が無くなりました。
＊ 例えば、ssh pi@raspberrypi.local   （raspberrypiの部分はホスト名です。）

わーい、わーい！とWebブラウザ（Edge,Chrome）でNode-REDに接続＊してみたら、・・・接続エラーが出るではありませんか！　念のため、Firefoxで行ってみたら、・・・うまく行く！
＊ http://raspberrypi.local:1880

（ちゃんと調べたわけではなく現象として）分かったことは、EdgeとChromeは、IPv6アドレス側を優先してHTTPサーバに接続要求を出す、ということです。そのため、Node-RED側ではIPv6接続で要求されたため拒否されてエラーになった模様です。

ということで**本題であるNode-REDのIPv6設定の仕方**を説明します。

## Node-REDの設定を変更する

### settings.jsを変更

何も考えずにラズパイにNode-REDを入れた場合、ホーム配下の.node-redフォルダにsettings.jsファイルがあります。これをテキストエディタで開き、20～30行あたりに注釈となっているuiHostパラメタを、以下のように修正してください。
```uiHost: "::",
```
Node-REDを起動し、WebブラウザからIPv6アドレスで接続できればOKです。
例）http://**[**IPv6アドレス**]**:1880　**ブラケット[]でアドレスを括ること！**

これでwindowsのwebブラウザから、Node-REDに
http://ホスト名.local:ポート番号
で接続できるようになります。

## おわりに
Chromeは、chrome://net-internals/#dns　とURL欄に入力するとhostnameとAddressのキャッシュ内容が表示できます。これを見てmDNSが引いた値がIPv6アドレスになっていることを発見し解決できました。
家にはラズパイやmDNSをライブラリでサポートしているESP32が多数あるので、これで色々と捗りそうです。
TransitionDrawableでFragmentをクロスフェード遷移させる


TransitionDrawableでFragmentをクロスフェードさせながら切り替えてみた。

色合いはさておき、なかなかカッコいい

使い所としては、アプリの紹介やチュートリアル画面あたりだろうか。

![](https://qiita-image-store.s3.amazonaws.com/0/52227/0b8ff513-dc5f-c048-456c-28dc1af9ded1.gif)

## 実装方法

まずdrawable内に`transition`タグのリソースxmlを作成する

```xml:trans.xml
<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/first" />
    <item android:drawable="@color/second" />
</transition>
```

このtrans.xmlを置き換えるレイアウトの背景に指定する。

```diff:activity_main.xml

   <FrameLayout
        android:id="@+id/main_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
+       android:background="@drawable/trans"
        />
```

これで準備OK
あとは`startTransition`にクロスフェードする時間を引数に渡して呼び出すだけ


```diff:MainActivity.kt

class MainActivity : AppCompatActivity() {

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

        fab.setOnClickListener {
+           val transition = main_container.background as TransitionDrawable
+           transition.startTransition(1000) //1秒かけてクロスフェード開始

+           supportFragmentManager
+                   .beginTransaction()
+                   .replace(R.id.main_container, SecondFragment())
+                   .commit()
        }
    }
```

これで`@color/first`から`@color/second`のクロスフェードが始まるので、その間に`FirstFragment`から`SecondFragment`へ切り替える。

切り替え後、戻す時は`reverseTransition`を使えば逆のクロスフェードになる。

```
transition.reverseTransition(1000)
```

```diff:MainActivity.kt
    override fun onBackPressed() {
+       val transition = main_container.background as TransitionDrawable
+       transition.reverseTransition(1000)

+       supportFragmentManager
+               .beginTransaction()
+               .replace(R.id.main_container, FirstFragment())
+               .commit()
    }
```

たったこれだけ、とても簡単

## 公式ドキュメント
TransitionDrawable  |  Android Developers https://developer.android.com/reference/android/graphics/drawable/TransitionDrawable

## 実装コード
今回のコードは以下にありまっせ

Android-Kotlin-Lab at TransitionDrawable 
https://github.com/ikemura23/Android-Kotlin-Lab/tree/TransitionDrawable
Redis5.0 の新機能と新データ型のStreamsの概要

Redis5.0のGAリリースが間近に迫っていますので、Redis5の新機能について簡単にまとめたいと思います。

# 主な追加/変更

リリースノートより抜粋。

```
1. The new Stream data type. https://redis.io/topics/streams-intro
2. New Redis modules APIs: Timers and Cluster API.
3. RDB now store LFU and LRU information.
4. The cluster manager was ported from Ruby (redis-trib.rb) to C code
   inside redis-cli. Check `redis-cli --cluster help` for more info.
5. New sorted set commands: ZPOPMIN/MAX and blocking variants.
6. Active defragmentation version 2.
7. Improvemenets in HyperLogLog implementations.
8. Better memory reporting capabilities.
9. Many commands with sub-commands now have an HELP subcommand.
10. Better performances when clients connect and disconnect often.
11. Many bug fixes and other random improvements.
12. Jemalloc was upgraded to version 5.1
```

## コマンドに影響する変更

### Streamデータ型の追加

ログ(時系列データ)を扱うことができるデータ型で、メッセージキューのように使うこともできます。
メッセージキューとして使う場合の、リストやPub/Subとの違いを別途説明します。

### Sorted Set型へのZPOPMIN/MAXの追加

Sorted Setをスコア順に並べた時の、先頭と末尾からデータをポップ(取得して削除)できます。
ブロッキング版のBZPOPMIN/MAXも追加されているので、キューのような使い方も可能になります。

### サブコマンドを持つコマンドへのHELPサブコマンドの追加

これはタイトルのままですが、HELPサブコマンドでヘルプテキストが見れるようになっています。
`OBJECT HELP` など。

## その他の変更

あとはほとんどCPU/メモリ効率に関する改善ですね。

Redis modules APIへのCluster、Timers APIの追加というのがありますが、Redis作者のAntierzさんのツイートによると、こちらのClusterというのはいわゆるRedis Clusterとは関係なく、Redisを使って分散処理を実現するための仕組みのようです。いずれのAPIも、同作者がRedisの技術を使って開発している分散メッセージキューシステムのDisqueのために追加したようです。

https://twitter.com/antirez/status/1001480576803704835

# Stream

これはログ(時系列データ)を扱うためのデータ型です。基本的に追記のみ可能なデータ型で、各データはタイムスタンプとハッシュのような連想配列データのペアになります。
StreamはPub/SubやListのBRPOPなどのようにリアルタイムに読み取りでき、Consumer Groupsという機能を使うことで、特定のグループ内で一度しかデータを読まないようにするといったことが可能になります。Consumer Groupsにおいては、データに処理済みをマークすることができ、メッセージキューとしての利用も意識した作りになっています。

## ListをBRPOPなどでキューとして使う場合との違い

 - 読み出してもデータが消えることはない
 - 複数のインスタンスから同じ内容を読み出すことができる

## Pub/Subとの違い

 - データ追加時に読み取り元が待機している必要がない
 - 読み取り元が複数いる場合に、一つの読み取り元だけに読み取りをさせることができる(Consumer Groups機能)

## メッセージキューとして使われることをより意識した実装

Consumer Groups機能ではグループ内の１つのConsumer(読み取り元)にだけデータを読み取らせることができます。また、読み取ったデータが滞留中データとして保持されます。`XACK`というコマンドで処理済みにすることで、滞留中データから削除されます。
これらの仕組みによって、ListやPub/Subと比べてメッセージキューとしてより安全に便利に使えるようになります。

# 参考
 - https://github.com/antirez/redis/blob/5.0/00-RELEASENOTES
 - https://redis.io/topics/streams-intro
GolangのインストールからHelloWorldまで

# 公式からパッケージをインストール
https://golang.org/dl/

インストールされたことを確認

```shell-session
$ go version
```

# HelloWorld
下記のファイルを作成

```go:helloworld.go
package main

import "fmt"

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

実行

```shell-session
$ go run helloworld.go
hello, world
```

ビルドして実行

```shell-sessionion
$ go build helloworld.go
$ ./helloworld
hello, world
```
PromiseKit

## 4秒後にさらに2秒後の処理

```swift
Promise<String> { (fulfill, reject) in
    DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(4), execute: {
        print("fulfill 1")
        fulfill("FFF")
        print("fulfill 2")
    })
    }.then {_ in
        Promise<String> { (fulfill, reject) in
            DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2), execute: {
                print("fulfill 3")
                fulfill("FFF")
                print("fulfill 4")
            })
        }
}

print("AAA")
```

### 結果
```
AAA
fulfill 1
fulfill 2
fulfill 3
fulfill 4
```

## 変数化してみようとしたけど、同時に走ってしまう
書き方を知らないだけかもしれないが下記のように、変数に代入すると同時に走ってしまった。

```swift
let p1 = Promise<String> { (fulfill, reject) in
    DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(4), execute: {
        print("fulfill 1")
        fulfill("FFF")
        print("fulfill 2")
     })
}

let p2 = Promise<String> { (fulfill, reject) in
    DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2), execute: {
        print("fulfill 3")
        fulfill("FFF")
        print("fulfill 4")
    })
}

print("AAA")
```

なぜ上記のように変数に入れたかったかというと次のように書けるのではないかと思ったから、
しかし、同時に処理は走ってしまった。

```swift
p1.then { _ in p2 }
```

### 関数化することでやりたかったことに近いことができる
```swift
func p1() -> Promise<String> {
    return Promise<String> { (fulfill, reject) in
        DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(4), execute: {
            print("fulfill 1")
            fulfill("FFF")
            print("fulfill 2")
        })
    }
}
    
func p2() -> Promise<String> {
    return Promise<String> { (fulfill, reject) in
        DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2), execute: {
            print("fulfill 3")
            fulfill("FFF")
            print("fulfill 4")
        })
    }
}

p1().then { [weak self] _ -> Void in
     guard let weakSelf = self else { return }
     
     _ = weakSelf.p2()
}
```
Bash と jq を使ってハッシュテーブルの配列のようなものを表現する

Bash でハッシュテーブルの配列を使いたくなったことはありませんか。
私は今デプロイスクリプトを書いていてそれが欲しくなりました。

調べてみると、Bash 4 には Dictionary と呼ばれるものがあるようです。
https://stackoverflow.com/questions/1494178/how-to-define-hash-tables-in-bash

ですが、手元の Macbook Pro の Bash のバージョンを調べてみたところ 3.2.57 と古かったので使えませんでした。
これをアップデートするのは簡単ですが、古い Bash しかない環境というのはよくあると思うので、別の方法を考えてみました。

## やってみた

```bash
#!/bin/bash -eu

# ハッシュテーブルの配列的なやつ
# 実際は JSON のストリーム
PARAMETERS=$(cat <<_EOT_
{
  "foo":"FOO 1",
  "bar":"BAR 1"
}
{"foo":"FOO 2","bar":"BAR 2"}
{
  "foo": "フー",
  "bar": "\u30d0\u30fc"
}
_EOT_
)

# Line-delimited JSON に変換
PARAMETERS=$(echo "${PARAMETERS}" | jq . --monochrome-output --compact-output)

# JSON を一つ一つ取り出して foo と bar の値をそれぞれ出力
while IFS='' read -r param || [[ -n "${param}" ]]; do
  foo=$(echo "${param}" | jq .foo -r)
  bar=$(echo "${param}" | jq .bar -r)

  echo "foo=${foo}"
  echo "bar=${bar}"

  echo "---"
done < <(echo "${PARAMETERS}")
```

```
$ bash json_stream.sh
foo=FOO 1
bar=BAR 1
---
foo=FOO 2
bar=BAR 2
---
foo=フー
bar=バー
---
```

* ヒアドキュメントで文字列として JSON を組み立てる
* 改行区切りで 1 行 1 JSON の Line-Delimited JSON に変換する
* ループで 1 JSON ずつ読み出す
  * https://stackoverflow.com/a/10929511
* ループ内では `jq .foo` といった感じで個別のプロパティを取り出す

何かのお役に立てば幸いです。
RailsをAPI専用で利用する準備

# これは何？
大規模なアプリケーションを開発したりする場合、
RailsをAPIサーバーとして利用し、APIクライアントは別に用意するケースが多い。
（弊社ではReactNative）

その時に、RailsをどのようにしてAPIサーバー専用とさせるのかの基礎知識を記載して行く。

僕も学びながらなので是非ご指摘あれば教えてください。

# API化に必要な知識
基本的には、APIクライアントからのHTTPリクエストが来たら、
そのリクエストに応じたレスポンスを返してあげるというそれだけ。
そのレスポンス部分だけをRailsでやりますよということ。

リクエストの形はHTTPリクエストなのでURLで来て、
Railsサーバーで色々ロジックを動かして、
**レスポンスの形はJSON形式で返してあげる**のが基本らしいです。

これで１セット。

なので、Railsで普段ウェブアプリケーションを開発している人からしても、取り立てて新しいことといえばJSONで出力するという部分だけ。
今回はそこを重点的に見ていきたいと思います。

# JSON出力
RailsでのJSON出力というと、`rabl`、`jbuilder`、`active_model_serializers`の三つがメインらしいです。

どれだけ高速にJSONを出力できるかのパフォーマンスで見ると、
`active_model_serializers`が非常に良いとのことなので、今回はそれを使って行きます。

# active_model_serializersを使って見る
まずは、使う為の下準備。
`gem 'active_model_serializers'`
`bundle install`

ちなみに、`jbuilder`は標準でGemfileに追加されてしまっている為、わかりやすくするためにコメントアウトしてもいいかもしれない。

## サンプルを作って動かす
今回はUserテーブルを作成して、そこにいくつかのデータをいれたものをブラウザでJSON出力できるかどうかまでを見ていきます。
※ 出力したいデータは適当に自分で突っ込んでください。

`bundle exec rails generate model User name:string email:string`
`bundle exec rails generate serializer User`

```ruby:routes.rb
get 'users/index'
```

```ruby:user.rb
#特に何もなし
```

```ruby:user_serializer.rb
attributes :id, :name, :email
```

```ruby:users_controllers.rb
def index
 @users = User.all
 render json: @users
end
```

ここまでできたら、あとはブラウザで、
`localhost:3000/users/index.json`
と打ち込めばUserテーブルに保存されているデータが出力されると思います。

ちなみに、Chromeで[JSONを見易くするアドオン](https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc/related)があるので是非使って見てください。

[こちらの記事](http://y-yagi.tumblr.com/post/63976647257/activemodelserializers%E3%82%92%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F)が大変参考になりましたので、応用したい方はこちらも見てください。
AndroidのImageViewに大きなBitmapをセットしようとしてBitmap too large to be uploaded into a texture

Android開発で、大きなBitMapをImageViewにセットしようとしたところ、以下のようなエラーが出て画像が表示されなかった。

```
Bitmap too large to be uploaded into a texture (3120x4160, max=4096x4096)
```

ImageViewに読み込む際に、ライブラリを通してやれば出来そうだったので、glideを使って無事解決。

* 変更前

``` java
imageView.setImageBitmap(bitmap);
```
* 変更後

```java
Glide.with(getContext()).load(bitmap).into(imageView);
```

### おまけ
AndroidのImage読み込みライブラリでメジャーなGlideとPicassoを簡単に比較
今回はリリースがより頻繁にされているglideを採用

* glide 
https://github.com/bumptech/glide
  * last update 7 days ago
  * last release 21 days ago

* picasso 
https://github.com/square/picasso
  * last update 12 days ago
  * last release 6 months ago