4

ルビー1.8.7、メインでrequireを使用できるのに、self.requireを使用できないのはなぜですか?

require('date') # ok
self.require('date') 
NoMethodError: private method `require' called for main:Object
from (irb):22
from /usr/lib/ruby/1.8/date.rb:437

mainがオブジェクトクラスであることはよく知られています:irb(main):045:0> self => main

irb(main):043:0> self.class
=> Object

しかし、私はそれがカーネルミックスインを持っていることを発見しました:

irb(main):042:0> self.class.included_modules
=> [Kernel]

さらに、requireは自己の私的な方法であることがわかりました。

irb(main):037:0> self.private_methods
=> [... "require", ...]

同様に、self.attr_accessorは使用できません。

irb(main):051:0> class X
irb(main):052:1> self.attr_accessor(:ssss)
irb(main):053:1> end
NoMethodError: private method `attr_accessor' called for X:Class
from (irb):52
from /usr/lib/ruby/1.8/date.rb:437

それはどのように起こったのですか?誰かがその質問を明確にすることができますか?

4

3 に答える 3

2

次の簡単な例を確認してください。

class Person
  def initialize(age)
    @age = age
  end

  def compare_to(other)
    # we're calling a protected method on the other instance of the current class
    age <=> other.age
  end

  # it will not work if we use 'private' here
  protected

  def age
    @age
  end
end

ruby には暗黙的および明示的なメソッド レシーバーがあります。次のコード スニペットを確認してください。

class Foo
  def a; end

  # call 'a' with explicit 'self' as receiver
  def b; self.a; end

  # call 'a' with implicit 'self' as receiver
  def c; a; end
end

基本的にRubyでは、メソッドが受信者でのみ(キーワードなしで)private呼び出すことができます。あなたの例では、モジュールを定義したメソッドであり、サブジェクトでのみ呼び出すことができます。implicitselfrequireprivateKernelimplicit

于 2012-04-25T12:39:25.550 に答える
2

requireプライベートメソッドです。したがって、そのまま呼び出すことはできません

Object.require 'date'

しかし、Ruby の eval/send メソッドで呼び出すことができます:

Object.send(:require, 'date')
# or
self.send(:require', 'date')

実際によく似ているのは

require 'date'

たとえば、pry コンソールは次のように解釈します。

instance_exec do
  require 'date'
end

Ruby インタプリタでもほぼ同じことができると思います。トップレベルのコマンドを にinstance_execブロックとして渡し、Object任意のプライベート メソッドを呼び出すことができます。

于 2012-04-25T12:52:00.150 に答える
0

プライベート メソッドは、暗黙的なレシーバーでのみ呼び出すことができます。これはrequire機能しますが、機能しself.requireないことを意味します。

プロテクト メソッドは で呼び出すことがselfでき、パブリック メソッドは任意のオブジェクトで明示的に呼び出すことができます。

それらが唯一の制限です。はい、サブクラスでプライベート メソッドを使用できsend、すべてのアクセス制御をバイパスします。

于 2012-04-25T13:28:37.940 に答える