إذا كان القرد الترقيع هو مسموح به في كل من روبي وبايثون, لماذا هو أكثر إثارة للجدل في روبي ؟

StackOverflow https://stackoverflow.com/questions/717506

سؤال

في العديد من المناقشات سمعت عن روبي في الناس قد أعربت عن تحفظات بشأن اللغة ، قضية القرد الترقيع يأتي باعتبارها واحدة من الشواغل الرئيسية.

ومع ذلك ، نادرا ما أسمع نفس الحجج المقدمة في سياق الثعبان على الرغم من أنه يسمح أيضا في لغة بايثون.

لماذا هذا التمييز ؟

هل الثعبان تشمل أنواع مختلفة من الضمانات للحد من مخاطر هذه الميزة ؟

هل كانت مفيدة؟

المحلول

كبرنامج Python الذي كان لديه طعم الروبي (ويحبها)، أعتقد أن هناك إلى حد ما بالتوازي المفارقات عندما بدأت بيثون شعبية.

سيؤدي مبرمجات جافا "باش" بيثون "باش"، تفيد بأنها ليست لغة حقيقية، وأن الطبيعة الديناميكية لأنواعها ستكون خطيرة، وتسمح للناس بإنشاء رمز "سيء". كما أصبحت بيثون أكثر شيوعا، وأصبحت مزايا وقت التطوير السريع الخاص بها واضحة، ناهيك عن بناء الجملة أقل حرفا:

// Java
Person p = new Person();
# Python
p = Person()

بدأنا في رؤية بعض الميزات الديناميكية التي تظهر في الإصدارات اللاحقة من Java. تجعل الأمر التنفسية و [إلغاء الصندوقات أقل مزعجة للتعامل مع البدائيات، وتسمح لنا Generic Code مرة واحدة وتطبيقها على العديد من الأنواع.

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

بالتأكيد، يمكنك المسمار بشكل سيء ويمكن أن تعطل البرنامج الخاص بك. يمكنني segfault في C بسهولة جدا، أيضا. ويمكن أن يموت تطبيقات Java الموت.

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

نصائح أخرى

إنها تقنية أقل تمارس في بيثون، جزئيا لأن الطبقات "الأساسية" في بيثون (تلك المنفذة في ج) ليست قابلة للتعديل حقا. في Ruby، من ناحية أخرى، بسبب الطريقة التي يتم بها تنفيذها داخليا (ليس أفضل، فقط مختلفة) فقط يمكن تعديل أي شيء ديناميكيا.

فلسفيا، إنه شيء يميل إلى عبوس داخل مجتمع بيثون، أقل بوضوح في عالم روبي. لا أعرف لماذا تؤكد أنه أكثر إثارة للجدل (هل يمكن أن يرتبط بمرجع موثوق به؟ - لقد كانت تجربتي أن تصحيح القرد هو تقنية مقبولة إذا كان ينبغي لأي منها أن يكون المستخدم على بينة من العواقب المحتملة.

قد تسمح اللغات بذلك، ولكن لم تكن المجتمع تكوين هذه الممارسة. Gonkepatching لا يغضن في أي لغة، لكنك تسمع عنها في كثير من الأحيان في روبي لأن شكل فئة مفتوحة يستخدم يجعلها من السهل جدا أن تكون من السهل جدا على الفئة وبسبب هذا، إنه أكثر قبولا في مجتمع Ruby، ولكن لا يزال عبئا. وبعد البديهة ببساطة ليست سائدة أو سهلة في بيثون، وهذا هو السبب في أنك لن تسمع نفس الحجج الموجهة إليه في هذا المجتمع. Python لا تفعل شيئا أن روبي لا يفعله لمنع هذه الممارسة.

السبب الذي تسمعه / يقرأ عنه في كثير من الأحيان في روبي هو أن هذا في روبي:

class MyClass
  def foo
    puts "foo"
  end
end
class MyClass
  def bar
    puts "bar"
  end
end

سوف تعطيك فئة تحتوي على طريقتين، foo و bar, ، في حين أن هذا في بيثون:

class MyClass:
    def foo(self):
        print "foo"
class MyClass:
    def bar(self):
        print "bar"

سوف تترك لك مع فئة تحتوي فقط على الطريقة bar, ، كما إعادة تعريف كبسولة من الفئة التعريف السابق تماما. إلى AmanyPatch في بيثون، عليك بالفعل كتابة هذا:

class MyClass:
    def foo(self):
        print "foo"
def bar(self):
    print "bar"
MyClass.bar = bar

وهو أصعب من إصدار روبي. هذا بمفرده يجعل رمز روبي أسهل بكثير من الردمة من كود بيثون.

"هل تشمل Python أنواعا مختلفة من الضمانات لتقليل مخاطر هذه الميزة؟"

نعم. المجتمع يرفض القيام بذلك. الحماية اجتماعية تماما.

في الواقع في بيثون، من الصعب بعض الشيء تعديل الأنواع الأساسية.

على سبيل المثال، تخيل، أنك أعاد تعريف عدد صحيح.

روبي:

class Fixnum 
   def *(n)
      5 
   end 
end

الآن 2 * 2 غلة 5.

بيثون:

>>> class int(int):
    def __mul__(self, x):
        return 5


>>> 2*2
4
>>> int(2)*int(2)
5

في بيثون، أي حرفية ("", {}, 1.0, ، إلخ) يخلق مثيل للفئة القياسية، حتى لو حاولت الرد على الفئة وتم إعادة تعريف الفئة المقابلة في مساحة اسمك.

هذا فقط لن يعمل كيف تقصد:

class str():
    # define your custom string type
    ...

a = "foo"      # still a real Python string
a = str("foo") # only this uses your custom class

أعتقد أن تصحيح القرد يجب أن يستخدم فقط كحل الأخير.

عادة ما يعرف مبرمجون Python كيف يتصرف فئة أو طريقة. إنهم يعرفون أن الفئة XXX تقوم بأشياء بطريقة معينة.

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

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

إذا كنت تريد أن تفعل بعض القرد الترقيع في بيثون ، فمن السهل نسبيا طالما كنت لا تعديل المدمج في نوع (int, float, str).

class SomeClass:
    def foo(self):
        print "foo"

def tempfunc(self):
    print "bar"
SomeClass.bar = tempfunc
del tempfunc

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

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