外部キー制約はとりあえず設定するべき(不要になったら外せばいい)
外部キー制約の話。
外部キー制約はつけたほうがいい。まず全部つけてから不要だったら外せばいい。
Rails界隈だとそもそも外部キー制約を理解していないし、使ったこともない人が多すぎる。
さらに言えばCHECK制約もつけるべきと考えている。
vim7.4でファイルを開いた時に先頭文字が「g」に置き換わる不具合の対処方法
CentOS7(64bit)でvim7.4を使ってみようと思い、最新のパッチ(764)を適用した上でビルドしたところ、タイトル通りの不具合が発生した。
2015/07/03時点では、ネットで同様の現象について書かれている記事を見つける事ができなかったので自分で書いておく。
自分はいつもTeraTermでsshでサーバに接続してvimを使っているのだが、この場合にこの問題が起きるようだ。
原因は不明だが、~/.vimrcが存在していると、たとえ~/.vimrcの中身が空であろうと、任意のファイルを開いた時に先頭の文字が「g」に置き換わってしまう。
vimにおいて.vimrcを使わないという選択肢はあり得ないので、この問題は放置できない。
パッチを適用しない状態でビルドした場合は、正常に動作する事から特定のパッチを適用した場合にこの現象が起きると思われる。
763、762、...、756という感じで1つずつ適用するパッチを減らしてビルドして動作確認を行った結果、756までは問題ない事が分かった。
つまり、パッチ757でこの問題が挿入されてしまったようだ。
結論としては、しばらくはvim7.4を自前でビルドして使いたい場合は、適用するパッチは756までにするという事にした。
追記
7.4.757のパッチのコメントを見ると、
「cannot detect the background color of a terminal」
と書いてあり、背景色に関わる何かであるように思われる。
いろいろググったところ、.vimrcにset background=darkを指定する(lightでも可)と良いというツイートを発見した。
実際に、.vimrcにset background=darkを追記してファイルを開いたところ、先頭文字がgに置き換わる問題が起きなかった。
最新パッチを使いたい場合は、この方法しかなさそうだ。
追記(7/8)
7.4.766にてこの問題が修正されたように思えたのだが、自分の環境では問題が解決しなかった。
「7.4.766 (after 7.4.757) bg color check does not work on Tera Term」
自分が使っているTeraTermが最新版ではなかったので、試しに最新版の4.87にして試したところ現象が起きなくなった。
TeraTerm4.87+パッチ766以降であれば問題が起きないという事で良さそうだ。
「通信の最適化」の回避策について考える
各キャリアが行っている「通信の最適化」が問題になっているが、これをアプリやAPIなどで回避する方法をまとめる。
以下のいずれかで回避できるはず。
ruby2.2でkyotocabinet-rubyがインストールできない問題の対処法
通常の流れとしては、
ruby extconf.rb
make
make install
で良いはずなのだが、ruby2.2で試したところエラーが発生した。
具体的なエラーはこのようなもの。
$ wget http://fallabs.com/kyotocabinet/rubypkg/kyotocabinet-ruby-1.32.tar.gz $ tar xvzf kyotocabinet-ruby-1.32.tar.gz $ cd kyotocabinet-ruby-1.32 $ ruby extconf.rb *** extconf.rb failed *** Could not create Makefile due to some reason, probably lack of necessary libraries and/or headers. Check the mkmf.log file for more details. You may need configuration options. Provided configuration options: --with-opt-dir --without-opt-dir --with-opt-include --without-opt-include=${opt-dir}/include --with-opt-lib --without-opt-lib=${opt-dir}/lib --with-make-prog --without-make-prog --srcdir=. --curdir --ruby=/home/watanabe/.rbenv/versions/2.2.2/bin/$(RUBY_BASE_NAME) --with-kyotocabinet-dir --without-kyotocabinet-dir --with-kyotocabinet-include --without-kyotocabinet-include=${kyotocabinet-dir}/include --with-kyotocabinet-lib --without-kyotocabinet-lib=${kyotocabinet-dir}/lib extconf.rb:18:in `<main>': uninitialized constant Config (NameError)
exitconf.rbのConfigという定数というかクラスが未定義という事でエラーになっている。
Configが使われている場所を調べる。
$ grep Config extconf.rb Config::CONFIG["CPP"] = "g++ -E"
ruby2.2ではConfigがRbConfigに変わっているので、ここを書き換えれば良いはず。
$ cp -a extconf.rb extconf.rb.bak $ sed -i 's/Config/RbConfig/g' extconf.rb $ diff extconf.rb extconf.rb.bak 18c18 < RbConfig::CONFIG["CPP"] = "g++ -E" --- > Config::CONFIG["CPP"] = "g++ -E"
再度、extconf.rbを実行すると無事成功!
$ ruby extconf.rb setting variables ... $CFLAGS = -I. -I/usr/local/include -Wall $(cflags) -O2 $LDFLAGS = -L. -L/home/watanabe/.rbenv/versions/2.2.2/lib -fstack-protector -rdynamic -Wl,-export-dynamic -L. -L/usr/local/lib $libs = -lkyotocabinet -lz -lstdc++ -lrt -lpthread -lm -lc checking for kccommon.h... yes creating Makefile
次にmakeを実行すると、またしてもエラー・・・。
$ make compiling kyotocabinet.cc kyotocabinet.cc: In static member function ‘static void NativeFunction::execute(NativeFunction*)’: kyotocabinet.cc:602: error: ‘rb_thread_blocking_region’ was not declared in this scope make: *** [kyotocabinet.o] Error 1
ネットで調べたところ、rb_thread_blocking_regionという関数がなくなったから起きているらしい。
kyotocabinet.ccの該当行は以下のようになっている。
600 static void execute(NativeFunction* func) { 601 #if defined(_KC_YARV_) 602 rb_thread_blocking_region(execute_impl, func, RUBY_UBF_IO, NULL); 603 #else 604 func->operate(); 605 #endif 606 }
_KC_YARV_が定義されていたらrb_thread_blocking_regionを使用するという事になっているが、
代替手段としてfunc->operate()が用意されている。
という事は、常にfunc->operate()を使うようにしてやれば良いはず。
調べたところ、_KC_YARV_ は601~605行目の処理のみで利用されているので影響範囲が小さい。
24 #if RUBY_VM >= 1 25 #define _KC_YARV_ 26 #endif
とりあえず、25行目を空にしてやれば良いだろう。
$ cp -a kyotocabinet.cc kyotocabinet.cc.bak $ sed -i 's/define _KC_YARV_//g' kyotocabinet.cc $ diff kyotocabinet.cc kyotocabinet.cc.bak 25c25 < # --- > #define _KC_YARV_
再度、makeを実行するとエラーが起きずにコンパイルが成功した。
$ make compiling kyotocabinet.cc linking shared-object kyotocabinet.so
とりあえず、インストールする。
$ make install
テストを実行して問題がないか確認するが、やっぱりエラー。
$ ruby test.rb test.rb:33:in `<main>': uninitialized constant Config (NameError)
例によってConfigをRbConfigにしてやれば良い。
影響範囲を調べる。なぜかRbConfigに直ってるやつもある・・・ $ grep Config test.rb rubycmd = Config::CONFIG["bindir"] + "/" + RbConfig::CONFIG['ruby_install_name'] $ cp -a test.rb test.rb.bak $ sed -i 's/rubycmd = Config/rubycmd = RbConfig/' test.rb $ diff test.rb test.rb.bak 33c33 < rubycmd = RbConfig::CONFIG["bindir"] + "/" + RbConfig::CONFIG['ruby_install_name'] --- > rubycmd = Config::CONFIG["bindir"] + "/" + RbConfig::CONFIG['ruby_install_name']
再度、テストを実行(少し時間かかる)すると、無事に全てのテストが成功。
$ ruby test.rb 001/105: kctest.rb order ':' '10000': ok 002/105: kctest.rb order -rnd ':' '10000': ok 003/105: kctest.rb order -etc ':' '10000': ok ... 105/105: kctest.rb misc 'casket.kcf': ok 105 tests were all ok
これで安心してruby2.2でもkyotocabinetを使う事が出来る。
jpmobileでundefined method `extract_handler_and_format_and_variant'という例外が発生する場合の対処方法
rails 4.0.8とjpmobile 4.1.2の組み合わせで以下のような例外が発生するようになった。
undefined method `extract_handler_and_format_and_variant' for #<Jpmobile::Resolver:0x007fc644bf8350>
解決したので書いておく。
エラーの原因
Jpmobile::ResolverはActionViewのextract_handler_and_format_and_variantを利用しているのだが、undefined methodという事でこのメソッドがなくなってしまったようだ。
extract_handler_and_formatという似た名前のメソッドを見つけたので、これ使えばいいんじゃね?という適当な理由で試してみた。
無事動いたので、一時しのぎ的な対応としては十分だろう。
データ構造とコードはどちらも重要である
こんな記事を見たので思うところを書いてみる。
【コンピュータサイエンス名言紹介 vol.1】Linus Torvaldsの考える「良いプログラマーが気にかけること」
この記事の中でポイントとなるのは、
「ダメなプログラマーはコードに気をつかう。良いプログラマーはデータ構造とそれらの関係に気をつかう。」
というところだろう。
おっしゃる事には同意するのだが、こういう強めの主張はグサッと心に刺さる反面、データ構造にさえ気を付ければ、どんなダメなコードを書いても良いプログラマなのだという誤解を招きかねないという心配をしてしまう。
上記の主張をされているのは、言うまでもなく経験の豊富な優れたプログラマーであり、きちんとしたコードを書ける人である。
きちんとしたコードが書けるという前提の元で、コードよりデータ構造のほうが大切なんだという事を言っているのであって、きちんとしたコードも書けないような人がデータ構造のほうが大切だとか抜かすのは大きな間違いであると思う。
自分自身も含めた一般的なレベルのプログラマは、データ構造もコードも大切だと考えるべきであると主張したい。
良いコードを書くにどうすればいいのか、良い設計とはどんな物なのかという事を常に気に掛けてレベルアップしていきたい。
jpmobileをTizenに対応させる方法(Rails3)
概要
jpmobileをTizenに対応させてみる を参考にしたというかほぼそのまま。
参考サイトでは、lib/以下にファイルを置いているけど、個人的には独自のパッチは、config/initializers/以下に配置するのがベストだと思うので、そっちのアプローチで対応してみた。
ソース
以下のソースをconfig/initializers/jpmobile_tizen.rbとして保存して、railsを再起動すれば完了!
# encoding: utf-8 # #== 概要 # jpmobileをTizeに対応させるパッチ module Jpmobile module Mobile DEFAULT_CARRIERS_WITH_TIZEN = DEFAULT_CARRIERS + ["Tizen"] def self.carriers if @carriers.nil? || @carriers == DEFAULT_CARRIERS @carriers = DEFAULT_CARRIERS_WITH_TIZEN.dup end @carriers end class Tizen < SmartPhone # 対応するUser-Agentの正規表現 USER_AGENT_REGEXP = /Tizen/ end end end
できるようになる事
ユーザエージェントにTizenを含む端末に対して以下の動作は確認できた。
- request.smart_phone?がtrueになる
- app/views/xxx_smart_phone.html.erb などスマートフォン用のビューが参照される