سؤال

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

choose :one => lambda {
    choose [a, b]
    if a
      raise "Illegal"
    end
  },
  :two => ....

حاليا، ستختار دائما "A" (والتي اتخذت بحد ذاتها تبدو أفضل) ولكنها تسبب مشاكل إلى أسفل. الإجراء: واحد مع خيار "B" لا يفكر أبدا.

لقد قمت بتشغيل CallCC (غير محمول لجميع تطبيقات روبي، من ما قرأته) والألياف (الجديدة في 1.9 ولا يمكن افتراض أن تكون متاحة) كأشياء قد تكون مقتنعة بالعمل، لكنني ليس مجنونا عن وجود برنامجين، أو عن السحر الأسود لأي منها، حقا.


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

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

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

المحلول

مرة أخرى، كما وعدت.

إليك عدد قليل من الأفكار:

  • يمكنك السلسلة من الخيارات مع العائد للقيام بعمل ترتيب التباديل. بمعنى آخر، اختر يمكن أن تقوم بإنشاء مجموعة من المحفوظات المتداخلة خارج الخيارات التي تم تمريرها إليها، وسوف تسفر عنها فقط في السلسلة التالية. الخروج من الكتلة المرفقة يضعك مباشرة بعد العائد؛ إذا كنت بحاجة إلى المزيد (مثل أسباب الفشل) يمكنك رفع وإنقاذ.
  • قد يقوم بذلك ترتيب غير تقليدي ل Three 'R (RESCUE، RIVY، وإعادة المحاولة) القيام بذلك، مرة أخرى بفكرة تختار تعشيش هيئات الخيار أو تضمينها في هيكل متداخلا.
  • إذا كانت الخيارات هي تأثير رخيصة وجانبي، فقد ترغب في النظر إلى إنتاج جميع التباديلات فقط والتكرار من خلالها.
  • إذا لم تكن هناك تأثير جانبي مجاني، فقد ترغب في تجربة نوع من الحل الزائف من موناد، حيث تنتج LAMALAL LAMBDAS لكل التقليب.
  • ما يعادل أكثر أو أقل (ولكن التعديل بعيدا عن سؤالك الأولي) قد تكون قادرا على تعيين فهرس (أسهل إذا تمكنت من تحديد بطاقة كل خيار، ولكن ممكن مع فهرس مجزز في أي حال) ويتكره من خلال الفهارس وبعد
  • تم ترحيل الألياف إلى 1.8.x

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

نصائح أخرى

قد ترغب في النظر في الحلول ل [هذا الاختبار] [1] للأفكار.

- Markusq.

[1]: http://www.rubyquiz.com/quiz70.html."هذا الاختبار"

PS أنا في طريقي إلى عرض تقديمي، لكنني سأحقق مرة أخرى وتقديم المزيد عندما أعود، إذا لم يصادف أحد آخر إلى اللوحة.

على النحو المطلوب، إليك مثال على ما قصدته بسلسلة الخيارات مع الغلة. قد يبدو تنفيذ عظام عارية شيء مثل هذا:

def choose_one_of_each(choices,results,&block)
    if choices.empty?
        yield results
      else
        c = choices.dup
        var,val = c.shift
        choose(val) { |v|
            choose_one_of_each(c,results.update(var => v),&block)
            }
      end
    end

def choose(options,&block)
    case options
      when Hash  then choose_one_of_each options,{},&block
      when Range then options.each { |item| yield item rescue nil }
      else            options.each { |item| yield item rescue nil }
      end
    end

وسيستخدمها مثل هذا (توسعت إلى حد ما من مثالك، لإظهار كيفية تفاعل الأجزاء):

a = 7
b = 'frog'
choose(
    :one => [a,b], 
    :two => ['stay','go','punt'], 
    :three => {:how => ['in the car','in a boat','by magic'],:how_fast => 0..2 }
  ) do |choices|
     raise "illegal" if choices[:one] == a
     raise "You can't stay fast!" if choices[:two] == 'stay' and choices[:three][:how_fast] > 0
     raise "You go that slow!"    if choices[:two] == 'go'   and choices[:three][:how_fast] < 1
     print choices.inspect,"\n"
     end

والتي من شأنها أن تنتج شيئا مثل هذا (بسبب الطباعة):

{:three=>{:how=>"in the car", :how_fast=>0}, :one=>"frog", :two=>"stay"}
{:three=>{:how=>"in the car", :how_fast=>0}, :one=>"frog", :two=>"punt"}
{:three=>{:how=>"in the car", :how_fast=>1}, :one=>"frog", :two=>"go"}
{:three=>{:how=>"in the car", :how_fast=>1}, :one=>"frog", :two=>"punt"}
{:three=>{:how=>"in the car", :how_fast=>2}, :one=>"frog", :two=>"go"}
{:three=>{:how=>"in the car", :how_fast=>2}, :one=>"frog", :two=>"punt"}
{:three=>{:how=>"in a boat", :how_fast=>0}, :one=>"frog", :two=>"stay"}
{:three=>{:how=>"in a boat", :how_fast=>0}, :one=>"frog", :two=>"punt"}
{:three=>{:how=>"in a boat", :how_fast=>1}, :one=>"frog", :two=>"go"}
{:three=>{:how=>"in a boat", :how_fast=>1}, :one=>"frog", :two=>"punt"}
{:three=>{:how=>"in a boat", :how_fast=>2}, :one=>"frog", :two=>"go"}
{:three=>{:how=>"in a boat", :how_fast=>2}, :one=>"frog", :two=>"punt"}
{:three=>{:how=>"by magic", :how_fast=>0}, :one=>"frog", :two=>"stay"}
{:three=>{:how=>"by magic", :how_fast=>0}, :one=>"frog", :two=>"punt"}
{:three=>{:how=>"by magic", :how_fast=>1}, :one=>"frog", :two=>"go"}
{:three=>{:how=>"by magic", :how_fast=>1}, :one=>"frog", :two=>"punt"}
{:three=>{:how=>"by magic", :how_fast=>2}, :one=>"frog", :two=>"go"}
{:three=>{:how=>"by magic", :how_fast=>2}, :one=>"frog", :two=>"punt"}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top