method_missingの速度計測
遅くなるとは聞いていたが、どんなもんか興味で単純な関数呼び出しでのベンチマークをしてみた。
method_missing と 通常呼び出しの検証結果
user | system | total | real | |
---|---|---|---|---|
通常呼び出し | 0.000000 | 0.000000 | 0.000000 | 0.000029 |
method_missing | 0.000000 | 0.000000 | 0.000000 | 0.000056 |
ざっくり見てみたところ
method_missing を利用したときは通常呼び出しの約2倍程度遅い
require 'benchmark' require 'pp' class MethodTest def method_missing(method_name, *args) args end def test(test) return test end end a = MethodTest.new puts Benchmark::CAPTION pp Benchmark.measure { 10000.times do |i| a.test('pool') end } pp Benchmark.measure { 10000.times { |i| a.hoge('pool') } }
クラスインスタンス変数とスコープ
気になったので、調べてみた
module Hoge module Moge class Test # クラスインスタンス変数 @hoge= ->{ p 'called!!'; 'aaaa'}.call # 特異メソッド def self.get p @hoge end # インスタンスメソッド def get p @hoge end end end end # クラスメソッドはクラスのインスタンス変数を見ることができる。 # 最初に読み込まれたタイミングで初期化がはしる Hoge::Moge::Test.get #=> called!! #=> aaaa # インスタンスメソッドはクラスインスタンス変数を見ることができない。 Hoge::Moge::Test.new.get #=> nil # クラスインスタンス変数の初期化は # 最初に読み込まれたタイミングの一度のみしか走らないようです。 Hoge::Moge::Test.get #=> aaaa
下記のようにクラス変数にするとどのメソッドからでも参照できます。
module Hoge module Moge class Test # クラスインスタンス変数 @@hoge= ->{ p 'called!!'; 'aaaa'}.call # 特異メソッド def self.get p @@hoge end # インスタンスメソッド def get p @@hoge end end end end # クラスメソッドはクラス変数を見ることができる。 Hoge::Moge::Test.get #=> called!! #=> aaaa # インスタンスメソッドはクラス変数を見ることができる。 Hoge::Moge::Test.new.get #=> aaaa
SQLite3::ReadOnlyException のエラー
ちょっとサイト作ってるときに、さっきまで普通に動作していたのに、
rake db:migrate:reset
を実行して、ブラウザから確認しようと思ったら、
SQLite3::ReadOnlyException : attempt to write a readonly database
との文字が。
調べてみると、どうやらパーミッションの問題のようです。
SQLite3::ReadOnlyException: attempt to write a readonly database
確認してみると、rootでコマンド実行してたから
sqliteのdbファイルのパーミッションがrootになってました・・・
$ chown user.user dbファイル名
で権限を変更して、もうブラウザで再チャレンジしたらうまくいきました。
おそくなりましたが、あけましておめでとうございます。
特定のインスタンスのみにメソッドを追加する
作成したインスタンスのみメソッド追加するやり方がわからなくて、
試してみたのでメモ
下記ソースコードは Test クラスのインスタンスの a に対して、
特異メソッドを追加してみたサンプルです。
class Test def hoge p 'pp' end end a = Test.new a.hoge #=> 'pp' # aの特異クラスに対して特異メソッドを定義する class << a def hoge p 'hogehgoe' end end a.hoge #=> 'hogehoge' # 新規クラス作成して確認 b = Test.new b.hoge #=> 'pp' # ほかのインスタンスに影響がない事がわかる #以下のように書いても同じ def a.hoge p 'hogehogehoge' end a.hoge #=> 'hogehogehoge'
Yuguiさんのこの記事がとても勉強になりました。
http://yugui.jp/articles/768
継承チェーンなどの、仕組みを分かって行けると楽しいですね。
もっと勉強します・・・
DotCloud で Node.js を 使う
本日は楽天テクノロジーカンファレンスに参加してきました。
いろいろと興味深い話が聞けましたが、それはまた機会があれば。
ホントいまさらって感じですが、DotCloud使ってみようかなと思い立って使ってみました。
最初は、Python が 2.4 の状態だったので dotcloud の cli をインストールするときに
"'str' object has no attribute 'format'"
というエラーが起きてました。
調べてみたところ、これは
format method was introduced in python 3.0 and backported only to 2.6
http://stackoverflow.com/questions/792721/attributeerror-str-object-has-no-attribute-format
との事でしたので、 Python をアップデートするところから書いてみます。
■準備
1.pythonのバージョン確認
$ python Python 2.4.3 (#1, Nov 11 2010, 13:30:19)
と 2.4 系だったので、2.6をyumでインストールします。
まず、epelレポジトリを追加。
$ rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
これで /etc/yum.repo.d/epel.repo が追加されているので、これを使ってインストールします。
$ yum -y install python26 --enablerepo=epel
2.easy_install のインストール
ソースのダウンロード(python2.6以上を使って行うこと)してインストールします。
$ wget http://peak.telecommunity.com/dist/ez_setup.py $ sudo /usr/bin/python26 ez_setup.py
確認します。
$ sudo easy_install error: No urls, filenames, or requirements specified (see --help)
3.dotcloudのcliインストール
下記コマンドでpipも一緒にインストールします。
$ sudo easy_install pip && sudo pip install dotcloud
確認と、APIキー(http://www.dotcloud.com/accounts/settings に書いてあります) を入力します。
$ dotcloud Warning: /root/.dotcloud/dotcloud.conf does not exist. Enter your api key (You can find it at http://www.dotcloud.com/accounts/settings): {ここにAPIキーを入力}
■ node.jsのプロジェクトをつくる & DotCloudの設定
"testapp" というアプリケーション名でデプロイしてみます。
今回は node.js でやります。
1.dotcloudに"testapp"というアプリケーション作成
$ dotcloud create testapp
Created application "testapp"
2.Projectディレクトリ & アプリケーションのディレクトリ作成
$ mkdir test-nodejs-dotcloud $ mkdir test-nodejs-dotcloud/nodetestapp
dotcloudの設定ファイル dotcloud.yml を作成します
$ vim test-nodejs-dotcloud/dotcloud.yml
下記を記述します。
# dotcloud.yml
www:
type: nodejs
approot: nodetestapp
管理ファイル supervisord.conf を作成します。
$ vim test-nodejs-dotcloud/nodetestapp/supervisord.conf
下記を記述します。
# supervisord.conf [program:node] command = node server.js directory = /home/dotcloud/current
node.js の サンプルファイルを作成します
$ vim test-nodejs-dotcloud/nodetestapp/server.js
下記を記述します。
# server.js var http = require('http'); http.createServer(function (req, res){ res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Node Test Application!'); }).listen(8080);
■とりあえず、デプロイしてみる
下記コマンドを実行してデプロイします。
$ dotcloud push testapp testapp/ # upload testapp/ ssh://dotcloud@uploader.dotcloud.com:443/testapp# rsync Pseudo-terminal will not be allocated because stdin is not a terminal. building file list ... done ./ dotcloud.yml nodetestapp/ nodetestapp/server.js nodetestapp/supervisord.conf sent 574 bytes received 98 bytes 103.38 bytes/sec total size is 308 speedup is 0.46 11:25:26 ---> Deploy of "testapp" scheduled for revision rsync-1321701925580 at 2011-11-19 11:25:26 11:25:26 ---> Initializing new services... (This may take a few minutes) 11:25:26 [www.0] Initializing... 11:25:40 [www.0] Service initialized 11:25:40 ---> All services have been initialized. Deploying code... 11:25:40 [www.0] The build started 11:25:41 [www.0] Fetched code revision rsync-1321701925580 11:25:47 [www.0] node: stopped 11:25:48 [www.0] node: started 11:25:48 [www.0] The build finished successfully 11:25:48 ---> Deploy finished Deployment finished. Your application is available at the following URLs www: http://testapp-xxxxx.dotcloud.com/
これで、デプロイは完了です。
デプロイ時に表示されたメッセージの最後にあるURL
http://testapp-xxxxxx.dotcloud.com/
にアクセスして、 "Node Test Application!!" と表示されていれば成功です。
噂どうり簡単ですね!
最近、DotCloudから「Now supporting MongoDB Replica Sets」とお知らせが来ていたので、
その辺りも試しつつ、今度は Node.js + MongoDB のアプリケーションをデプロイしてみたいと思います。
ありがとうございました。