سؤال

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

وهكذا يمكن أن أفعله:

a=['|','/','-','\\']
aNow=0
# ... skip setup a big loop
print a[aNow]
aNow += 1
aNow = 0 if aNow == a.length
# ... do next step of process
print "\b"

ولكن اعتقد انها تريد ان تكون أنظف القيام به:

def spinChar
  a=['|','/','-','\\']
  a.cycle{|x| yield x}
end
# ... skip setup a big loop
print spinChar
# ... do next step of process
print "\b"

وبالطبع الدعوة spinChar تريد كتلة. إذا أعطيها كتلة انها سوف يتعطل أجل غير مسمى.

وكيف يمكنني الحصول على مجرد yeild القادم من هذه الكتلة؟

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

المحلول

ولا يعمل روبي yield في الطريق ومثال الخاص شابه ذلك. ولكن هذا قد يكون مكانا جيدا ل إغلاق :

def spinner()
  state = ['|','/','-','\\']
  return proc { state.push(state.shift)[0] }
end

spin = spinner

# start working
print spin.call
# more work
print spin.call
# etc...

في ممارسة وأعتقد أن هذا الحل قد يكون أيضا "ذكية" لمصلحتها، ولكن فهم فكرة <لأ href = "http://www.rubycentral.com/pickaxe/ref_c_proc.html" يختلط = "نوفولو noreferrer "> Proc الصورة يمكن أن تكون مفيدة على أية حال.

نصائح أخرى

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

spinChar=Generator.new{ |g|
  ['|','/','-','\\'].cycle{ |x|
    g.yield x
  }
}
#then
spinChar.next
#will indefinitly output the next character.

والزيادات array index عادي مع معامل على مجموعة المجمدة ويبدو أن أسرع.

وموضوع فلاد هو أنيق ولكن ليس بالضبط ما أردت. وفي spinner class أن الزيادة من سطر واحد يكون أجمل إذا كان معتمدا روبي i++ مثل GLYPHS[@i++%GLYPHS.length]

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

وwith_spinner تشاك هو في الواقع قريبة جدا إلى ما أردت، ولكن لماذا كسر إذا لم يكن لديك لمع مولد النحو الوارد أعلاه.

وفاديم، وذلك بفضل لافتا الى generator سيكون بطيئا.

"Here's a test of 50,000 spins:"
                   user       system     total       real
"array index"      0.050000   0.000000   0.050000 (  0.055520)
"spinner class"    0.100000   0.010000   0.110000 (  0.105594)
"spinner closure"  0.080000   0.030000   0.110000 (  0.116068)
"with_spinner"     0.070000   0.030000   0.100000 (  0.095915)
"generator"        6.710000   0.320000   7.030000 (  7.304569)

وأعتقد أنك تسير في مسارها الصحيح مع cycle. ماذا عن شيء مثل هذا:

1.8.7 :001 > spinner = ['|','/','-','\\'].cycle
 => #<Enumerable::Enumerator:0x7f111c165790> 
1.8.7 :002 > spinner.next
 => "|" 
1.8.7 :003 > spinner.next
 => "/" 
1.8.7 :004 > spinner.next
 => "-" 
1.8.7 :005 > spinner.next
 => "\\" 
1.8.7 :006 > spinner.next
 => "|" 

وأنا لا أعتقد أنك تفهم تماما ما يفعل yield في روبي. فإنه لا يرجع قيمة من كتلة - يمر قيمة <م> إلى كتلة قمت تمريرها إلى الأسلوب إرفاق

وأعتقد أنك تريد شيئا أكثر من هذا القبيل:

def with_spinner
  a=['|','/','-','\\']
  a.cycle do |x|
    print x
    $stdout.flush # needed because standard out is usually buffered
    yield # this will call the do-block you pass to with_spinner
  end
end

with_spinner do
  #process here
  #break when done
end

وذات مرة، كتبت مجموعة. ولكنها ليست مجرد مجموعة، انها مجموعة لديها مؤشر، حتى تتمكن من الاتصال foreverrr القادم! http://gist.github.com/55955

وزوج هذه الفئة مع مكرر بسيطة أو حلقة وأنت الذهبي.

 a = Collection.new(:a, :b, :c)
 1000.times do |i|
   puts a.current
   a.next
 end

والتعليمات البرمجية الخاصة بك قليلا من الداخل إلى الخارج، إذا كان عليك عفوا قول ذلك. :)

لماذا لا:

class Spinner
  GLYPHS=['|','/','-','\\']
  def budge
    print "#{GLYPHS[@idx = ((@idx || 0) + 1) % GLYPHS.length]}\b"
  end
end

spinner = Spinner.new
spinner.budge
# do something
spinner.budge
spinner.budge
# do something else
spinner.budge

على الآن ، أو إذا كنت تريد شيئا مثل:

with_spinner do
  # do my big task here
end

... ثم عليك أن على استخدام متعدد خيوط : ل

def with_spinner
  t = Thread.new do
    ['|','/','-','\\'].cycle { |c| print "#{c}\b" ; sleep(1) }
  end
  yield
  Thread.kill(t) # nasty but effective
end

والكالينجيون، والجواب أعلاه الألغام هو كل القذرة.

a=['|','/','-','\\']
a << a
a.each {|item| puts item}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top