سؤال

بخلاف self.class.send :method, args..., بالطبع.أود أن جعل معقدة الأسلوب المتاحة في كل فئة سبيل المثال مستوى دون تكرار التعليمات البرمجية.


تحديث:

@جوناثان Branam:كان هذا الافتراض ، ولكن أردت أن أتأكد أن لا أحد آخر قد وجدت طريقة حولها.الرؤية في روبي هي مختلفة جدا عن تلك التي في جاوة.أنت أيضا على حق ، private لا يعمل على أساليب الفئة ، على الرغم من هذا سوف يعلن خاصة فئة الطريقة:

class Foo
  class <<self
    private
    def bar
      puts 'bar'
    end
  end
end

Foo.bar
# => NoMethodError: private method 'bar' called for Foo:Class
هل كانت مفيدة؟

المحلول

هنا مقتطف الشفرة للذهاب جنبا إلى جنب مع السؤال.باستخدام "خاص" في فئة التعريف لا ينطبق على أساليب الفئة.تحتاج إلى استخدام "private_class_method" كما في المثال التالي.

class Foo
  def self.private_bar
    # Complex logic goes here
    puts "hi"
  end
  private_class_method :private_bar
  class <<self
    private
    def another_private_bar
      puts "bar"
    end
  end
  public
  def instance_bar
    self.class.private_bar
  end
  def instance_bar2
    self.class.another_private_bar
  end
end

f=Foo.new
f=instance_bar # NoMethodError: private method `private_bar' called for Foo:Class
f=instance_bar2 # NoMethodError: private method `another_private_bar' called for Foo:Class

أنا لا أرى طريقة للالتفاف حول هذا.الوثائق تقول أنه لا يمكنك تحديد تلقي من أسلوب خاص.أيضا يمكنك فقط الوصول إلى أسلوب خاص من نفس الدرجة.فئة فو هو كائن مختلف من معين مثيل فو.

لا يمكن الإجابة النهائية.أنا بالتأكيد لست خبيرا ولكن أردت أن توفر التعليمات البرمجية المتكررة حيث أن الآخرين الذين يحاولون الإجابة بشكل صحيح خاصة أساليب الفئة.

نصائح أخرى

اسمحوا لي أن تسهم هذه القائمة من أكثر أو أقل غريب حلول غير الحلول:

puts RUBY_VERSION # => 2.1.2

class C
  class << self
    private def foo
      'Je suis foo'
    end
  end

  private define_method :foo, &method(:foo)

  def bar
    foo
  end
end

puts C.new.bar # => Je suis foo
puts C.new.foo # => NoMethodError

إذا كان الأسلوب هو مجرد وظيفة الأداة (أي أنها لا تعتمد على أي المتغيرات سبيل المثال), هل يمكن وضع طريقة إلى الوحدة ، include و extend حتى أنه متاح في كل صف خاص وأسلوب خاص سبيل المثال الأسلوب.

في الوقت الحاضر لا تحتاج مساعد أساليب بعد الآن.يمكنك ببساطة مضمنة مع تعريف الأسلوب.هذا يجب أن يشعر مألوفة جدا جافا الناس:

class MyClass

  private_class_method def self.my_private_method
    puts "private class method"
  end

  private def my_private_method
    puts "private instance method"
  end

end

و لا, لا يمكنك استدعاء خاص فئة الأسلوب من أسلوب مثيل.ومع ذلك ، يمكن أن تنفذ بدلا من ذلك على خاصة فئة الطريقة العامة أسلوب فئة في خاصة متداخلة فئة بدلا من ذلك باستخدام private_constant مساعد الأسلوب.انظر هذا blogpost للحصول على مزيد من التفاصيل.

هذا هو الطريق إلى لعب مع "ريال مدريد" خاصة أساليب الفئة.

class Foo
  def self.private_bar
    # Complex logic goes here
    puts "hi"
  end
  private_class_method :private_bar
  class <<self
    private
    def another_private_bar
      puts "bar"
    end
  end
  public
  def instance_bar
    self.class.private_bar
  end
  def instance_bar2
    self.class.another_private_bar
  end
  def calling_private_method
    Foo.send :another_private_bar
    self.class.send :private_bar
  end
end
f=Foo.new
f.send :calling_private_method 
 # "bar"
 # "hi"
Foo.send :another_private_bar
# "bar"

هتافات

وربما هذا هو الأكثر "الأم الفانيليا روبي" الطريقة:

class Foo
  module PrivateStatic # like Java
    private def foo
      'foo'
    end
  end
  extend PrivateStatic
  include PrivateStatic

  def self.static_public_call
    "static public #{foo}"
  end

  def public_call
    "instance public #{foo}"
  end
end

Foo.static_public_call # 'static public foo'
Foo.new.public_call # 'instance public foo'
Foo.foo # NoMethodError: private method `foo' called for Foo:Class
Foo.new.foo # NoMethodError: private method `foo' called for #<Foo:0x00007fa154d13f10>

مع بعض روبي metaprogramming, بل يمكن جعلها تبدو وكأنها:

class Foo
  def self.foo
    'foo'
  end

  extend PrivateStatic
  private_static :foo
end

روبي metaprogramming قوية جدا, بحيث يمكن من الناحية الفنية تنفيذ أي قواعد تحديد النطاق قد ترغب.أن يقال, كنت لا تزال تفضل وضوح الحد الأدنى مفاجأة من الخيار الأول.

إلا أنا سوء الفهم لا تحتاج فقط شيء من هذا القبيل:

class Foo
    private
    def Foo.bar
        # Complex logic goes here
        puts "hi"
    end

    public
    def bar
        Foo.bar
    end
end

بالطبع يمكنك تغيير التعريف الثاني إلى استخدام الذاتية الخاصة بك.فئة.إرسال النهج إذا أردت تجنب hardcoding اسم الفئة...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top