重新定义File::dirname ruby方法

重新定义File::dirname ruby方法,ruby,Ruby,我正在尝试重新定义File.dirname方法,以首先将%20s更改为空格。但是下面给了我一个错误 class File old_dirname = instance_method(:dirname) define_method(:dirname) { |s| s = s.gsub("%20"," ") old_dirname.bind(self).call(s) } end 这显示NameError异常:类“File”的未定义方法“di

我正在尝试重新定义File.dirname方法,以首先将%20s更改为空格。但是下面给了我一个错误

class File
   old_dirname = instance_method(:dirname)    

   define_method(:dirname) { |s|
       s = s.gsub("%20"," ")
       old_dirname.bind(self).call(s)
   }
end
这显示NameError异常:类“File”的未定义方法“dirname”


正确的方法是什么?

dirname
是文件的类方法,而不是实例方法,所以您只需要定义一个新的实例方法。另外,方法别名的惯用方法是使用
alias
。因此:

class <<File
  alias old_dirname dirname
  def dirname(f)
    old_dirname(f.gsub("%20", " "))
  end
end
class小心点

您正在改变方法的行为,而不仅仅是它的实现。这通常是糟糕的做法,因为它削弱了API作为可靠合同的价值


而不是考虑将输入转换成接收点。

< P>正如恰克·巴斯已经写的,“代码>文件::Drime< /Class >是<代码>文件< /Cl>类对象的单点方法(或者更确切地说是<代码>文件/<代码>类对象的元类的实例方法),而不是<代码>文件< /Cl>类> ./p>的实例方法。 因此,您必须打开
文件
的元类,而不是
文件
类本身:

#!/usr/bin/env ruby

class << File
  old_dirname = instance_method :dirname

  define_method :dirname do |*args|
    old_dirname.bind(self).(*args).gsub '%20', ' '
  end
end

require 'test/unit'
class TestFileDirname < Test::Unit::TestCase
  def test_that_it_converts_percent20_to_space
    assert_equal '/foo bar/baz', File.dirname('/foo%20bar/baz/quux.txt')
  end
end
#/usr/bin/env ruby

类这与他问题中发布的代码@jrhicks不同!这段代码用剩余的
File::old_dirname
方法污染了
文件
元类的名称空间,而问题中的原始代码非常小心地避免了这个问题。Chuck,关于范围的讨论是完全正确的,但是Jörg是正确的:
别名_方法
可能是“惯用的,”但它肯定不如OP最初的方法安全。