のえら

技術備忘とかメモとか.間違いはつっこんでいただきたい所存.アフィリエイトはやっていません.

【vim】NeoCompleteを使いたくてlua付きvimをインストールしてviコマンドで使うのに色々ハマった

NeoCompleteを使いたかったのでlua付きの最新vimをインストールするのに色々ハマった。
察しのよい人はもうタイトルからお気づきかと思われますが、vimのインストールはできていたのにviコマンドで呼び出すように設定していなかったというオチです。
まあ他にもインストール時にpython周りでエラーになったのでまた同じことを繰り返さないためにもメモ。
前提として、NeoCompleteはインストール済み。

Homebrewを使って最新のlua付きvimをインストールする。
vim にオプション --with-lua を指定するとluaが有効になっている状態でインストールできるとのことだったので実行。

$ brew install vim --with-lua
==> Using the sandbox
==> Downloading https://github.com/vim/vim/archive/v8.0.0596.tar.gz
Already downloaded: /Users/user_name/Library/Caches/Homebrew/vim-8.0.0596.tar.gz
==> ./configure --prefix=/usr/local --mandir=/usr/local/Cellar/vim/8.0.0596/share/man --enable-multibyte --with-tlib=ncurses --enable-cscope --with-
==> make
Last 15 lines from /Users/user_name/Library/Logs/Homebrew/vim/02.make:
clang -c -I. -Iproto -DHAVE_CONFIG_H -DMACOS_X_UNIX -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -o objects/undo.o undo.c
ang -c -I. -Iproto -DHAVE_CONFIG_H -DMACOS_X_UNIX -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -o objects/userfunc.o userfunc.c
clang -c -I. -Iproto -DHAVE_CONFIG_H -DMACOS_X_UNIX -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -o objects/window.o window.c
clang -c -I. -I/usr/local/include -Iproto -DHAVE_CONFIG_H -DMACOS_X_UNIX -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -o objects/if_lua.o if_lua.c
clang -c -I. -g -DPERL_DARWIN -fno-strict-aliasing -fstack-protector -I/System/Library/Perl/5.18/darwin-thread-multi-2level/CORE -Iproto -DHAVE_CONFIG_H -DMACOS_X_UNIX -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -o objects/if_perl.o auto/if_perl.c
clang -c -I. -g -DPERL_DARWIN -fno-strict-aliasing -fstack-protector -I/System/Library/Perl/5.18/darwin-thread-multi-2level/CORE -Iproto -DHAVE_CONFIG_H -DMACOS_X_UNIX -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -o objects/if_perlsfio.o if_perlsfio.c
clang -c -I. -I/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/include/python2.7 -DPYTHON_HOME='"/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7"' -fPIE -Iproto -DHAVE_CONFIG_H -DMACOS_X_UNIX -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -o objects/if_python.o if_python.c
clang -c -I. -I/Users/user_name/.rbenv/versions/2.4.0/include/ruby-2.4.0 -I/Users/user_name/.rbenv/versions/2.4.0/include/ruby-2.4.0/x86_64-darwin16 -DRUBY_VERSION=24 -Iproto -DHAVE_CONFIG_H -DMACOS_X_UNIX -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -o objects/if_ruby.o if_ruby.c
if_python.c:67:10: fatal error: 'Python.h' file not found
#include
^
1 error generated.
make[1]: *** [objects/if_python.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [first] Error 2

READ THIS: http://docs.brew.sh/Troubleshooting.html

These open issues may also help:
vim package installation error - configure: error: cannot run C compiled programs. https://github.com/Homebrew/homebrew-core/issues/12323

コンパイルエラー・・・。
pythonは入っていたはず、と思い確認してみる。

$ python --version
Python 3.5.0

うむ、入ってますな。
と、エラーメッセージで指定しているpythonのバージョンが違うことに気がつく。
色々確認。

$ which python3
/Users/user_name/.pyenv/shims/python3

$ which python
/Users/user_name/.pyenv/shims/python

コンパイルで指定しているpathと異なる。。

$ pyenv versions
system
* 3.5.0 (set by /Users/user_name/.pyenv/version)

途中で、.bash_profileでpythonのhome_pathをしていたことを思い出す。
プロジェクトで使うのに書いた気がするのでアンインストールは怖い。
コンパイルには2.7系を使っているようなのでとりあえず切り替える。

$ pyenv global system
$ pyenv versions
* system (set by /Users/user_name/.pyenv/version)
3.5.0

$ pyenv rehash
$ python --version
Python 2.7.13

再度インストール。

$ brew install vim --with-lua
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> Updated Formulae
caddy

==> Using the sandbox
==> Downloading https://github.com/vim/vim/archive/v8.0.0596.tar.gz
Already downloaded: /Users/user_name/Library/Caches/Homebrew/vim-8.0.0596.tar.gz
==> ./configure --prefix=/usr/local --mandir=/usr/local/Cellar/vim/8.0.0596/share/man --enable-multibyte --with-tlib=ncurses --enable-cscope --with-
==> make
==> make install prefix=/usr/local/Cellar/vim/8.0.0596 STRIP=/usr/bin/true

できた!

$vi --version

  1. lua と表示されることを確認したので、vi hoge.rbを開いて確認してみるものの、動作しない。。

vi上でコマンド打ってみる。

:NeoCompleteEnable
=> does not work with this version of vim

最新のvim入ったのになんで・・・?
使用しているvimがどこにあるのか確認してみる

$ which vim
=> /usr/local/bin/vim

$ which vi
=> /usr/bin/vi

あっ・・・(察し)

切り替える。

$ cd /usr/local/bin; ln -s vim vi

できた!

他のプラグインもなんか挙動がおかしいと思っていたら、ずっと vi と vim 気にせずに古いバージョン使ってたからか。。

Google Bigquery の WEB インターフェースのクエリエラー メモ

Bigquery のクエリエラーで(無駄に)ハマったところ

WITH BASE AS (
SELECT
count(id) as total
FROM
 `dataset_name.hoge_*`
WHERE
_TABLE_SUFFIX BETWEEN '20170501' AND '20170510'
)
SELECT
total
FROM
BASE

Bigqueryには実行前にクエリをチェックしてくれる機能があり、WITH句を書いていたら以下のようなエラーが表示された。
※このクエリはWITH句を含みたかっただけなので内容が適当です

エラーメッセージがこちら↓

Error: Encountered " "WITH" "WITH "" at line 1, column 1. Was expecting:

前日まで同様のクエリで問題なかったので、なぜ急に・・・?と色々構文チェックしていたけど、標準SQLを指定するのを忘れていただけだった(ブラウザ再起動後だった)

クエリ実行画面の「show options」を押して「SQL Dialect」の「Use Legacy SQL」のチェックを外せばOK

【rails3】POSTしたらルーティングエラーになったけどSSL設定的なものだった

※rails3での話

ssl_requirement
https://github.com/bartt/ssl_requirement
(railsSSLを使えるようにするgem)

起きたこと

特定の path に対して POST を投げたらルーティングエラーになってしまった。
指定している path のルーティングは routes に記述し、rake routesでも確認済みなので、ブラウザの開発者ツールで network を確認したら、指定の path の直後に同じ path に対して GET をかけていた。
確かに、この path に対してルーティング設定で GET は許可していないので、ルーティングエラーになるのは頷ける。
が、GET は意図して動作させていない。。
どこかでリダイレクトがかかっているみたいだったので確認したところ、ssl 接続の設定が絡んでいた。
今回指定した path は ssl_requirement を使用して HTTP で接続すると HTTPS にリダイレクトがかかるように設定されていて、ここのリダイレクトで GET になるためエラーが発生。
開発環境と本番環境でプロトコル変更するようにしておかないと動作確認に影響が出る。。
が、Rails.env.production? などで条件を指定してプロトコル変更するようにするのは微妙。
と思って gem の README をよく読んだらプロトコル切り替えられるようにできていた!

https://github.com/bartt/ssl_requirement#ssl-url-helper

hoge_path を hoge_path(secure: true) に変更して解決。
secureを指定すると、http と https を実行環境によって切り替えてくれる。
※環境設定で、SslRequirement.disable_ssl_check = true を指定している場合

react というか JSX のコメントアウト

sample.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <script src="http://fb.me/react-0.13.3.js"></script>
    <script src="http://fb.me/JSXTransformer-0.13.3.js"></script>
  </head>
  <body>
    <div id="app"></div>
    <script type="text/jsx">
      // コンポーネント宣言
      var Counter = React.createClass({
        // 初期値設定
        getInitialState() {
          return { count: 0 };
        },  
        // クリック時の処理
        onClick() {
          this.setState({count: this.state.count + 1});
        },  
        // コンポーネントを返す
        render() {
          return (
            <div>
              {// state の count を読み込む
              }   
              <div>count:{this.state.count}</div>
              {/* 
                クリック時にクリックイベント呼び出し
              */}                                                                                                                                      
              <button onClick={this.onClick}>click!</button>
            </div>
          );  
        }   
      }); 
      // 描画
      React.render(<Counter />, document.getElementById('app'));
    </script>
  </body>
</html>

こんな感じで、
{// ... }

{/* ... */}
で書ける。

前者は終わりの } を改行しないとエラーになるので注意する。
sample.html をブラウザで開いてデベロッパーツールで確認すると、改行していない場合以下のようなエラーがコンソールに表示されている。

Uncaught Error: Parse Error: Line 18: Unexpected token {
at file:///Users/xxx/work/sample.html

{/*
^
at file:///Users/xxx/work/sample.html

{/*
^

rescueを1行で書きたい

JSONでパースをかけるときに、変換できない形式のときにエラーになる。
空かどうかのチェックは事前にできるけど、パースができるかのチェックはできないようなので、nilで返してその後処理をするよう。
が、これだけのためにbegin句で複数行になるのは微妙かな?と思って調べてみると、1行でかけることがわかった。

橋本商会 » Rubyのrescueって1行で書くと値を返すのね・・

(以下、ざっくりとした例)

return nil if str.blank? # ここで事前チェックしたりなんだり
result  = begin
  JSON.parse(str)
rescue => e
  nil
end
str = '['
JSON.parse(str) rescue nil

が、rubocopの規約に引っかかったので、可読性を上げるためにも素直に複数行で書くようにしました。。

Style/RescueModifier:
Description: 'Avoid using rescue in its modifier form.'
StyleGuide: '#no-rescue-modifiers'
Enabled: true

※エラーの種別を判断して、きちんと処理しろということであってるのかしら。。
exceptions - Ruby-style-guide - Womply - Relish

【rails】solrのfacetでカラムごとにまとめたときの件数が100しか取得できない

solrでfacetを使うと、指定したカラムごとにまとめた結果を取得することができる。

results = User.search do
  facet(:hoge_ids, :foo_ids)
end
results.facet(:hoge_ids).rows

これはhoge_idsとfoo_idsでまとめて、facet(:hoge_ids).rowsでhoge_idsの結果を取得している。
このとき、まとめた件数が100件以上あっても上限が100件になってしまう。

# return 100
results.facet(:foo_ids).rows.count

max100件の設定も指定もしてないよなぁ、と思って調べてみると、readmeに書いてあった。。読もうね自分!
GitHub - sunspot/sunspot: Solr-powered search for Ruby objects

By default Sunspot will only return the first 100 facet values. You can increase this limit, or force it to return all facets by setting limit to -1.

 -1を指定しろとのこと。

User.search do
  facet(:hoge_ids)
  # 対象のカラムのみ指定する
  facet(:foo_ids, limit: -1)
  # どちらも全件返したいときは、1行ずつ指定する必要がある(引数まとめて書けない)
end

参考URL:
http://stackoverflow.com/questions/24388263/faceting-with-solr-sunspot-gem-facets-quantity-limit
https://groups.google.com/forum/#!topic/ruby-sunspot/yPXwPtzJSLI

【ruby】配列Aの中に配列Bの値が含まれているか確認したい

配列Aの中に配列Bの値が一つ以上含まれているか確認したくて、ぐるぐる回せばいいかなぁと思って書いたコードが以下。
※present?はrailsのArray拡張メソッド

[1] pry(main)> list1 = %w(apple banana melon)
=> ["apple", "banana", "melon"]
[2] pry(main)> list2 = %w(watermelon grape apple)
=> ["watermelon", "grape", "apple"]

[3] pry(main)> list1.any? { |f| list2.include?(f) }
=> true

もっとシンプルにかけないかと思い、改めてArrayの仕様を確認したところ、 & で配列の共通要素を返してくれることがわかったので、書き直した。

[4] pry(main)> (list1 & list2).present?
=> true
[5] pry(main)> (list1 & list2).empty?
=> false
[6] pry(main)> (list1 & list2).any?
=> true

値が含まれない場合の結果。

[7] pry(main)> list2 = %w(watermelon grape lemon)
=> ["watermelon", "grape", "lemon"]

[8] pry(main)> list1.any? { |f| list2.include?(f) }
=> false

[9] pry(main)> (list1 & list2).present?
=> false
[10] pry(main)> (list1 & list2).empty?
=> true
[11] pry(main)> (list1 & list2).any?
=> false