曜日べつゲリ統計
Mo 13 (18.1%) Tu 14 (19.4%) We 10 (13.9%) Th 9 (12.5%) Fr 11 (15.3%) Sa 6 (8.3%) Su 9 (12.5%)
ひさしぶりにとった。土曜日にむかうにつれて減るようだ
Mo 13 (18.1%) Tu 14 (19.4%) We 10 (13.9%) Th 9 (12.5%) Fr 11 (15.3%) Sa 6 (8.3%) Su 9 (12.5%)
ひさしぶりにとった。土曜日にむかうにつれて減るようだ
たとえば use みたいな感じのシステムをつくるとしても、あんまり使うイメージがうかばない。require "use" みたいなのは必要になってしまうし、require とは全然違う挙動をするから、なじむまでこまるし、中で何をやっているのかパっと見わからないから、ちょっとこわいし……(require はなにやってるのかわかりやすい)
というか RubyGems の何がいやか。なにを改善したらいいのか。パッチかけばすむのか。それでできるならそれにこしたことない。
require "rubygems" で定義される Module(Class) と読みこまれるファイル
["Gem::OperationNotSupportedError", "Gem::Exception", "Gem::LoadError", "Gem"] ["rubygems.rb", "rbconfig.rb", "rubygems/rubygems_version.rb", "thread.rb", "rbconfig/datadir.rb", "rubygems/source_index.rb", "rubygems/user_interaction.rb", "rubygems/remote_fetcher.rb", "net/http.rb", "net/protocol.rb", "socket.bundle", "timeout.rb", "uri.rb", "uri/common.rb", "uri/generic.rb", "uri/ftp.rb", "uri/http.rb", "uri/https.rb", "uri/ldap.rb", "uri/mailto.rb", "yaml.rb", "yaml/syck.rb", "syck.bundle", "yaml/basenode.rb", "yaml/ypath.rb", "yaml/baseemitter.rb", "yaml/constants.rb", "yaml/encoding.rb", "yaml/error.rb", "yaml/loader.rb", "yaml/stream.rb", "yaml/rubytypes.rb", "date.rb", "rational.rb", "date/format.rb", "yaml/types.rb", "zlib.bundle", "rubygems/digest/sha2.rb", "digest/sha2.bundle", "digest.bundle", "rubygems/digest/digest_adapter.rb", "forwardable.rb", "time.rb", "parsedate.rb", "rubygems/specification.rb", "rubygems/version.rb", "rubygems/security.rb", "rubygems/gem_openssl.rb", "openssl.rb", "openssl.bundle", "openssl/bn.rb", "openssl/cipher.rb", "openssl/digest.rb", "openssl/ssl.rb", "openssl/buffering.rb", "openssl/x509.rb", "rubygems/custom_require.rb"]
けっきょくいい方法がおもいつかなくて require にもどっていくのだなぁ……飽きるまで考えてみよう
依存ライブラリは次のバージョンから?かなり減るらしい。6ファイルぐらいに
「あるクラス・モジュール・メソッドがどこで定義されたものなのか簡単に知る方法がない」と書いたけど、ホントにホント?という切っ掛けで、メソッド内側の binding なら caller つかえば簡単にとれるけど、外から名前を指定してはとれないよなぁと思うので考えてみた。
class Object
def location_of_method(name)
c = nil
ret = callcc {|c| false }
unless ret
m = self.method(name)
args = [nil] * m.arity.abs
set_trace_func Proc.new {|event, file, line, id, binding, klass|
case event
when "c-call"
if id == name
set_trace_func(nil)
c.call([:native, nil])
end
when "call"
set_trace_func(nil)
c.call([file, line])
end
}
m.call(*args)
set_trace_func(nil) # attr_* 系で定義されたメソッドは call が trace できない?
end
ret
end
end
class Class
def location_of_instance_method(name)
self.allocate.location_of_method(name)
end
end
p Object.location_of_method(:new) #=> [:native, nil]
p Object.location_of_instance_method(:instance_eval) #=> [:native, nil]
require "pathname"
p Pathname.location_of_instance_method(:absolute?)
#=> ["/usr/lib/ruby/1.8/pathname.rb", 404]
require "ostruct"
p OpenStruct.location_of_instance_method(:initialize)
#=> ["/usr/lib/ruby/1.8/ostruct.rb", 46]
class OpenStruct
def initialize
end
end
# 直前の
p OpenStruct.location_of_instance_method(:initialize)
#=> ["test.rb", 44]
o = Object.new
def o.singleton_method_foo
end
# 直前の
p o.location_of_method(:singleton_method_foo)
#=> ["test.rb", 51]
require "webrick"
p WEBrick::HTTPServer.location_of_instance_method(:mount)
#=> ["/usr/lib/ruby/1.8/webrick/httpserver.rb", 111]set_trace_func と callcc (継続) を使ってる。activesupport の Binding#of_caller の実装を少し前にみて「うわきめー」って思って使う機会があったら使ってみたい、とか考えていたら意外にホイホイあった。やってみてわかったことは set_trace_func 内のデバッグがすごくむずかしいということだった。
もっと簡単にやる方法があるかなぁ……
しかしモジュール定義とかはどうやってとるかがわからなすぎる。現在のファイルと require してるファイルを全部見てくしかないよねたぶん……
Delegater 使ってるときにうまくいかないなぁ。そもそも call がよばれてこない。なんでだろう。
require "tempfile"
p Tempfile.location_of_instance_method(:unlink)
__END__
(eval):3:in `__send__': undefined method `unlink' for class `NilClass' (NameError)
from (eval):3:in `location_of_method'
from test.rb:32:in `location_of_instance_method'
from test.rb:85Tempfile にも unlink が定義されているはずなのに、それが呼ばれない?で、スーパークラスのデリゲートが呼ばれているように見える。どういうことだろう……
なぜか Tempfile.allocate が nil になる
むーどうして allocate が nil になるかわからない。ちゃんと Class.allocate がよばれてるみたいなのに……
もうちょい改良
class Object
def location_of_method(name)
old_state = Thread.critical
Thread.critical = true
name = name.to_sym
c = nil
ret = callcc {|c| false }
unless ret
m = self.method(name)
args = [nil] * m.arity.abs
set_trace_func Proc.new {|event, file, line, id, binding, klass|
case event
when "c-call"
if id == name
set_trace_func(nil)
c.call([:native, nil, binding, klass])
end
when "call"
set_trace_func(nil)
c.call([file, line, binding, klass])
end
}
begin
m.call(*args)
rescue Exception
end
set_trace_func(nil)
end
ret
rescue ArgumentError
false
ensure
Thread.critical = old_state
end
end
class Class
def location_of_instance_method(name)
ret = nil
old_state = Thread.critical
Thread.critical = true
self.ancestors.each do |c|
break if c == Object
[:location_of_method, :method_missing, :allocate].each do |m|
[c, (class <<c; self; end)].each do |klass|
begin
klass.module_eval <<-EOC
alias __location_temp_#{m} #{m}
remove_method :#{m}
EOC
rescue NameError
end
end
end
end
begin
ret = self.__send__(:allocate).location_of_method(name)
rescue NotImplementedError, TypeError, NoMethodError => e
p e
end
self.ancestors.each do |c|
break if c == Object
[:location_of_method, :method_missing, :allocate].each do |m|
[c, (class <<c; self; end)].each do |klass|
begin
klass.module_eval <<-EOC
alias #{m} __location_temp_#{m}
remove_method :__location_temp_#{m}
EOC
rescue NameError
end
end
end
end
ret
ensure
Thread.critical = old_state
end
end
class Module
def location_of_instance_method(name)
c = Class.new
# included を実行させない
self.__send__ :append_features, c
c.location_of_instance_method(name)
end
end
#-- Test
def __modules
ret = []
ObjectSpace.each_object(Module) do |o|
ret << o
end
ret
end
before = __modules
require "rubygems"
require "active_support"
require "active_record"
module_files = {}
(__modules - before).each do |o|
next if o.name.nil? || o.name.empty?
o.instance_methods(false).each do |m|
r = o.location_of_instance_method(m.to_sym)
if r
(module_files[o.to_s] ||= []) << r.first unless r.first == :native
end
module_files[o.to_s] &&= module_files[o.to_s].uniq
end
end
require "pp"
pp module_files
http://lab.lowreal.net/trac/browser/config/.vim/plugin/lusty-explorer.vim.ext-ri.vim
\li でひらくようにデフォ設定。選択して RET で、そのまま補完候補バッファで ri のドキュメントを表示する。hjkl はプロンプトの入力にとられてしまっているけど C-p C-n で動ける。(ri のコマンドを ri にきめうちしてるので変えないとだめ。二箇所ある)
ほんとはもうちょい違う挙動にしたかったのだけど、めんどいので既存のを拡張する方向にした。Lusty-Explorer は Ruby だし簡単にできてよいよい。
ってかちょっと重すぎるなぁ……gems でライブラリいれてるとやばい
あれ、なんか C-c とか C-g で消えてくれない。なんでだろう
バッファ名がまずかったらしい。[LustyExplorer-ri] だとなぜか t という名前に変わってしまう。[LustyExplorer-Ri] だと大丈夫。よくわかんないな……vim のほうがそういう仕様なのかなぁ……