سؤال

def foo
  f = Proc.new { return "return from foo from inside proc" }
  f.call # control leaves foo here
  return "return from foo" 
end

def bar
  b = Proc.new { "return from bar from inside proc" }
  b.call # control leaves bar here
  return "return from bar" 
end

puts foo # prints "return from foo from inside proc" 
puts bar # prints "return from bar" 

اعتقدت return الكلمة كان اختياري في روبي و انك دائما returnجي سواء طلب ذلك أو لا.بالنظر إلى أن أجد أنه من المستغرب أن foo و bar يكون الإخراج المختلفة على الرغم من حقيقة أن foo يحتوي على صريح return في Proc f.

لا أحد يعرف لماذا هذا هو الحال ؟

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

المحلول

روبي ثلاثة ثوابت:

  1. A كتلة ليس كائن تم إنشاؤه من قبل { ... } أو do ... end.
  2. A proc هو Proc كائن تم إنشاؤه من قبل Proc.new أو proc.
  3. A امدا هو Proc تم إنشاؤها من قبل lambda (أو proc في روبي 1.8).

روبي ثلاث كلمات أن يعود من شيء:

  1. return ينهي طريقة أو امدا في.
  2. next ينهي كتلة, بروك, أو امدا في.
  3. break ينهي الطريقة التي تسفر عن كتلة أو الاحتجاج بروك أو امدا في.

في lambdas, return يتصرف مثل next, مهما كانت الأسباب. next و break تسمى الطريقة التي هي لأنها هي الأكثر شيوعا مع أساليب مثل each, حيث إنهاء كتلة سوف يؤدي التكرار إلى السيرة الذاتية مع القادم عنصر من المجموعة وإنهاء each سوف يسبب لك كسر الخروج من الحلقة.


إذا كنت تستخدم return داخل تعريف foo, سوف يعود من foo, حتى لو كان داخل كتلة أو proc.العودة من كتلة ، يمكنك استخدام next الكلمة بدلا من ذلك.

def foo
  f = Proc.new { next "return from foo from inside proc" }
  f.call # control leaves foo here
  return "return from foo" 
end
puts foo # prints "return from foo"

نصائح أخرى

هذه هي دلالات على Procs ؛ ليس بالضرورة دلالات لجميع الكتل.أنا أوافق هذا هو مربكا بعض الشيء.ومن هناك لمزيد من المرونة (وربما جزئيا سبب روبي لديه المواصفات باستثناء تنفيذه).

السلوك هو محدد في Proc التنفيذ. Lambdas تتصرف بشكل مختلف, لذلك إذا كنت تريد الخاص بك returns لا خروج من أرفق طريقة استخدام lambdas.أو حذف return الكلمة من Proc.

تحقيق عميق من Rubys الإغلاق هنا.أنها رائعة فضح.

لذلك:

def foo   
  f = Proc.new {
    p2 = Proc.new { return "inner proc"};
    p2.call
    return "proc"
  }
  f.call
  return "foo"
end

def foo2
  result = Proc.new{"proc"}.call
  "foo2 (proc result is: #{result})"
end

def bar
  l = lambda { return "lambda" }
  result = l.call
  return "bar (lambda result is: #{result})"
end

puts foo
# inner proc
puts foo2
# foo (proc result is: proc) 
puts bar
# bar (lambda result is: lambda) 

وأعتقد أنه من هذا الطريق: Proc.new مجرد خلق كتلة من التعليمات البرمجية التي هي جزء من وظيفة الدعوة. إجراءات / امدا خلق وظيفة مجهولة المصدر التي لديها ارتباطات خاصة. وهناك أمثلة التعليمات البرمجية صغيرة تساعد:

def foo
  f = Proc.new { return "return from foo from inside Proc.new" }
  f.call # control leaves foo here
  return "return from foo" 
end

وما يعادل

def foo
  begin
    return "return from foo from inside begin/end" }
  end

  return "return from foo" 
end

وهكذا فمن الواضح أن وعودة فقط العودة من وظيفة "فو '

وعلى النقيض:

def foo
  f = proc { return "return from foo from inside proc" }
  f.call # control stasy in foo here
  return "return from foo" 
end

وما يعادل (تجاهل الارتباطات نظرا لعدم المستخدمة في هذا المثال):

def unonymous_proc
  return "return from foo from inside proc"
end

def foo
  unonymous_proc()
  return "return from foo" 
end

والذي هو كما هو واضح لن يعود من فو والاستمرار في العبارة التالية بدلا من ذلك.

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