找到了一个 workaround
old = :+
new = :plus__
Fixnum.class_eval "alias #{new} #{old}"
确实 alias_method 可以传变量,多谢指点!
知道对 method 使用的,比如下面这段代码,想把 :old_plus 和 :+ 先赋给变量,再来使用 alias,就会报错。
class Fixnum
alias :old_plus :+
def +(value)
self.old_plus(value).old_plus(1)
end
end
new --> new_name 一样不行。
monkey patch 能有效吗?alias 是 ruby 的 keyword,不是 method。
你的运行环境是怎样的呀?
因为例子中的代码改写了 + 的结果为正确结果 +1,因此当定义完 + (method)后,C:/Ruby22/lib/ruby/site_ruby/2.2.0/rbreadline.rb 里的表达式做加法运算时出现了对数组索引越界的错误。但是为何有些环境下就正常运行呢(比如 Linux)?
我的出错信息是这样的。当前在 Windows 上使用的是 ruby 2.2.6, 试过 ruby 2.4.2, 结果是一样的。是不是哪里配置不对?
irb(main):001:0> class Fixnum
irb(main):002:1> alias :old_plus :+
irb(main):003:1* def +(value)
irb(main):004:2> self.old_plus(value).old_plus(1)
irb(main):005:2> end
irb(main):006:1> end
=> :+
C:/Ruby22/lib/ruby/site_ruby/2.2.0/rbreadline.rb:1716:in `block in expand_prompt': no implicit conversion of nil into St
ring (TypeError)
from C:/Ruby22/lib/ruby/site_ruby/2.2.0/rbreadline.rb:1696:in `each'
from C:/Ruby22/lib/ruby/site_ruby/2.2.0/rbreadline.rb:1696:in `expand_prompt'
from C:/Ruby22/lib/ruby/site_ruby/2.2.0/rbreadline.rb:1784:in `rl_expand_prompt'
from C:/Ruby22/lib/ruby/site_ruby/2.2.0/rbreadline.rb:1809:in `rl_set_prompt'
from C:/Ruby22/lib/ruby/site_ruby/2.2.0/rbreadline.rb:4821:in `readline'
from C:/Ruby22/lib/ruby/site_ruby/2.2.0/readline.rb:45:in `readline'
from C:/Ruby22/lib/ruby/2.2.0/irb/input-method.rb:150:in `gets'
from C:/Ruby22/lib/ruby/2.2.0/irb.rb:469:in `block (2 levels) in eval_input'
from C:/Ruby22/lib/ruby/2.2.0/irb.rb:623:in `signal_status'
from C:/Ruby22/lib/ruby/2.2.0/irb.rb:468:in `block in eval_input'
from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:188:in `call'
from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:188:in `buf_input'
from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:103:in `getc'
from C:/Ruby22/lib/ruby/2.2.0/irb/slex.rb:205:in `match_io'
from C:/Ruby22/lib/ruby/2.2.0/irb/slex.rb:75:in `match'
from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:282:in `token'
from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:264:in `lex'
from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:235:in `block (2 levels) in each_top_level_statement'
from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:231:in `loop'
from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:231:in `block in each_top_level_statement'
from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:230:in `catch'
from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:230:in `each_top_level_statement'
from C:/Ruby22/lib/ruby/2.2.0/irb.rb:485:in `eval_input'
from C:/Ruby22/lib/ruby/2.2.0/irb.rb:395:in `block in start'
from C:/Ruby22/lib/ruby/2.2.0/irb.rb:394:in `catch'
from C:/Ruby22/lib/ruby/2.2.0/irb.rb:394:in `start'
from C:/Ruby22/bin/irb:11:in `<main>'
但是在 Linux 上试了 ruby 1.8.7,功能正常,输出如下,和上面的输出相比,=>:+ 变成了 => nil, 这又是什么原因?
irb(main):001:0> class Fixnum
irb(main):002:1> alias :old_plus :+
irb(main):003:1* def +(value)
irb(main):004:2> self.old_plus(value).old_plus(1)
irb(main):005:2> end
irb(main):006:1> end
=> nil
谢谢指点! 通过对文档里的 inspect 方法的返回值(AClass.method 或者 AClass#method)进行判断,可以用来区分 class method 还是 instance method。 但是,如果要判断 public 还是 private,似乎没提供直接的方法。
经过验证,这段代码是查找类似 .dir_a 这样的以 dot 开头且跟有名字的目录,而对 . 目录本身不起作用。
谢谢给位的指点!
特别欣赏这种授之以渔的解答 那行代码里的意思是寻找以 . 开头的 directory,那么 . 目录(当前目录)能被搜到吗?还是一定要 . 开头的有名字的目录,比如 .dir_a。
就是想找在哪里定义了这种用法。无奈不知从何下手,多谢指点! 顺便问一下,为何将#4 里的那段代码删除,也不会影响运行结果?每个目录下应该都有 . 目录的呀。
试了下原帖里的代码,即便把下面这段都去掉,也不会影响运行结果 所以很难确定 ?. 就等同于 "." :
if File.basename(path)[0] == ?.
Find.prune # Don't look any further into this directory.
else
next
end
原帖代码
require 'find'
puts ""
puts "-----------------------File Search-----------------------------------"
puts ""
print "Enter the search path : "
searchpath = gets
searchpath = searchpath.chomp
puts ""
print "Enter the search pattern : "
pattern = gets
pattern = pattern.chomp
puts"----------------------------------------------------------------------"
puts "Searching in " + searchpath + " for files matching pattern " + pattern
puts"----------------------------------------------------------------------"
puts ""
Find.find(searchpath) do |path|
if FileTest.directory?(path)
if File.basename(path)[0] == ?.
Find.prune # Don't look any further into this directory.
else
next
end
else
if File.fnmatch(pattern,File.basename(path))
puts "Filename : " + File.basename(path)
s = sprintf("%o",File.stat(path).mode)
print "Permissions : "
puts s
print "Owning uid : "
puts File.stat(path).uid
print "Owning gid : "
puts File.stat(path).uid
print "Size (bytes) : "
puts File.stat(path).size
puts "---------------------------------------------------"
end
end
end
谢谢指点! 关于这样的用法?. 在哪里有文档说明吗?
解决了。
ruby_config() { ruby1.9 -rrbconfig -e "puts Config::CONFIG['$1']" | grep -v "ruby 1.9.0"; }
gcc embed.c -o embed \
-I ruby_config rubyhdrdir
\
-I ruby_config rubyhdrdir
/ruby_config arch
\
-L ruby_config libdir
\
ruby_config LDFLAGS
\
ruby_config LIBS
\
ruby_config LIBRUBYARG
参考 http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/14864 http://blog.csdn.net/wu4long/article/details/4048759
为啥我发不了贴