0

use ruby version is 2.0.0p648

I want extend File Class returns change "extend". But returned method returns is normal function.

Why returned normal function?

class File
  alias_method :__open__, :open

  def open()
    'extend'
  end
end

p File.open('test.txt')
#<File:test.txt>

1 Answers1

0
class File
  class << self
    alias_method :__open__, :open

    def open(*)
      'extend'
    end
  end
end

File.open('test.txt') # => "extend"
File.__open__('test.txt') # => #<File:test.txt>

Explanation

File.open is a class method, yet you are aliasing and redefining at the instance scope. To alias a class method, you will need to do so on the singleton class. You can do this with the syntax class << self; end. To oversimplify things, accessing the singleton class essentially lets you use instance level syntax at the class scope, so you can also define class methods there without preceding the method name with self. e.g. self.open

Once you're redefining File.open you'll want to respect the API of the original method as pertains to arguments. If your overriding method doesn't use any arguments as in your example, then you can give a splat * operator as the single parameter. This means that the method can take 0 or more arguments without throwing an error, but they won't be used in the method body. Otherwise, if you define the method with the signature def open() (or the equivalent and stylistically preferred def open) then you'll get an ArgumentError when you call Foo.open('test.txt') because you're passing more arguments than the method expects.

class File
  class << self
    alias_method :__open__, :open

    def open
      'extend'
    end
  end
end

File.open('test.txt') # => ArgumentError: wrong number of arguments (given 1, expected 0)
m. simon borg
  • 2,515
  • 12
  • 20