shebangってなに...`require': cannot load such fileエラーで２日かかった話。


結論... shebangで指定すべきインタプリタを誤って設定していた。　:sob:　`※コメントだとおもっていた件`
---
**前提をお伝えすると、
ソースコードのフローチャートを自動化してくれるGemを、ソースコード可視化ツールを作りたかった。
 こんなの↓**
![class_worker.gif](https://qiita-image-store.s3.amazonaws.com/0/367758/fe016e54-b1e6-1a79-7672-4650c280f46d.gif)
関連記事：[Rails要らず、CGIとRubyでソースコードをフローチャートにするツール作成](https://qiita.com/taishinagasaki/items/a874e70a79c1fa142909)
関連リポジトリ：[VisualizeSrc](https://github.com/taishinagasaki/visualize_src)

### 詰まったところ
Gemを読み込みのための`require bundle/setup` で「該当ファイルないぞ」って怒られる。
 **エラー内容は↓**

```
/usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- bundler/setup (LoadError), referer: http://localhost/index.cgi
```

###状況を整理すると

- 特定の実行Rubyファイル(A)にて、`require bundler/setup`がロードエラーになっていた.
    - rbenvで環境指定はできている。
    - 同じ環境下の他のRubyファイル(B)は実行は可能
        - かつRubyファイル(B)では`require bundler/setup`は成功する
        - しかし、Rubyファイル(B)をRubyファイル(A)に取り込んで処理させると、やはり上述のロードエラーになる。
- 権限問題も解消
    - 全て777に変更してみたが、それでも解決せず。

**問題ソースコードはこちら**

```rb
# 問題ファイル(result.rb)中身
----
  1 #! usr/bin/ruby
  2 require "bundler/setup" ← ここで死んでいた。
  3 require 'cgi'
  4 cgi = CGI.new
  5 print "Content-Type: text/html\n\n"
  6 print "<html>\n"
  7 print "<head>\n"
  8 print "<title>CGI Test</title>\n"
  9 print "</head>\n"
 10 print "<body>\n"
 11 print "<a href=\"/form.cgi\">\"こちらのページから画像が見れます\"</a>"
 12 print "</body>\n"
 13 print "</html>\n"
 14 $src = cgi["sub"]
...
```

####エラー内容を詳しくみてみる。
**教えてApache先生 :bow_tone1: 
apacheのエラーログを見てみると、(再掲になるが↓)**

```apache
# /var/log/httpd/error_logのログ
/usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- bundler/setup (LoadError), referer: http://localhost/index.cgi
```
- エラーの内容から明らかに、pathに誤りがあることがわかる。
    - 失敗箇所は先に触れているが、指定ファイルがrequireできない、というもの...
    - おそらく指定しているファイル/ロードパスに誤りがある...

*心の声（その１）*
>　ん？でも、同じ環境下に作っているruby fileなのに１つは実行可能で、もう一つは実行不可能ってどういうこと?? Why Ruby！

※ちなみに、`/usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55`をggるとたくさん、悩んでいる人がいた印象。軒並み検証してみましたが、解決せず。requireのあとに指定しているパスが間違っているよ、というアドバイスが多かった印象でした。

#### ということで、冷静にみましょう、ロードパス :thinking:

```rb
RubyGems Environment:
  - RUBYGEMS VERSION: 3.0.2
  - RUBY VERSION: 2.3.8 (2018-10-18 patchlevel 459) [x86_64-linux]
  - INSTALLATION DIRECTORY: /usr/local/rbenv/versions/2.3.8/lib/ruby/gems/2.3.0
  - USER INSTALLATION DIRECTORY: /root/.gem/ruby/2.3.0
  - RUBY EXECUTABLE: /usr/local/rbenv/versions/2.3.8/bin/ruby
  - GIT EXECUTABLE: /usr/bin/git
  - EXECUTABLE DIRECTORY: /usr/local/rbenv/versions/2.3.8/bin
  - SPEC CACHE DIRECTORY: /root/.gem/specs
  - SYSTEM CONFIGURATION DIRECTORY: /usr/local/rbenv/versions/2.3.8/etc
  - RUBYGEMS PLATFORMS:
    - ruby
    - x86_64-linux
  - GEM PATHS:
     - /usr/local/rbenv/versions/2.3.8/lib/ruby/gems/2.3.0
     - /root/.gem/ruby/2.3.0
  - GEM CONFIGURATION:
     - :update_sources => true
     - :verbose => true
     - :backtrace => false
     - :bulk_threshold => 1000
  - REMOTE SOURCES:
     - https://rubygems.org/
  - SHELL PATH:
```

*心の声（その２）*
>うん、rbenvで指定できている。。。Why Ruby！

と、もうわからん。頭を抱えているとshebangに出会ったのでした。
-
*天の声(その１)*
> [shebang/シバン(Unix)](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%90%E3%83%B3_(Unix)) ってのがあるんだよ??
>[引用] シバンまたはシェバン (英: shebang) とはUNIXのスクリプトの #! から始まる1行目のこと。起動してスクリプトを読み込むインタプリタを指定する。ハッシュ・バンまたはシェル・バン、シャープ・バンとも言うが、これらを縮めたシェバンという呼び方が一般的かつ簡素である。*

####rbenv指定のrubyとgemが正しく指定できてなかった。shebangの指定先が間違っていた...YES, Ruby！！！
||本来使いたかったもの(正解)|誤って設定していたもの|
|:--|:--|:--|
|設定したshebang|#! /usr/local/rbenv/versions/2.3.8/bin/ruby|#! usr/bin/ruby|
|結果|この配下にgemは存在するので成功する|gemをinstallしていないので、ロードエラーになる|

本来は`#! /usr/local/rbenv/versions/2.3.8/bin/ruby`にすべて設定していて、ここを使いたかった。が、問題Rubyファイル(A)では特に関係のない(設定していない)インタプリタを指定してしまっていた。
**恥ずかしながら、<font color="Red">shebangをずっとコメントだとおもっていた</font>ため、原因特定が難しかった。**
最終的には`gem env`で右記を確認「RUBY EXECUTABLE: /usr/local/rbenv/versions/2.3.8/bin/ruby」して、shebang指定してあげたらOKだった。

#####[補足] 助けてくれた資料達...thanks!!
- [#!/bin/sh は ただのコメントじゃないよ！ Shebangだよ！](https://qiita.com/mohira/items/566ca75d704072bcb26f)
- [Perl, Python 及び Ruby スクリプトにおける正しいshebangの書き方](https://qiita.com/tueda/items/369215b99316b2e9f3d8)
- [「#!/usr/bin/python」と「#!/usr/bin/env python」の違い](http://zashikiro.hateblo.jp/entry/2012/09/22/125953)
- [いまさら聞けない、#! で始まる１行目の名前とenv指定時の挙動](https://japanrock-pg.hatenablog.com/entry/20100319/1268968887)

#####[余談] そもそもbundler/setupが何をしているのかは、こちらの記事がわかりやすかった。
- [Bundler入門 - setupとrequire を読み解く](https://qiita.com/kotaroito/items/52ab922f74bee83a9006)
    - 要はgemファイルを一括で読み込んでいる
    - gem同士の互換性を保ちながら各gemの導入、管理を行ってくれるのがBundler

---
*お読み頂きありがとうございました。
以上になります。誰かのお役に立てば...
なにか間違っていたり、ベターな方法がある場合はご教示いただけると幸いです。*