রুবিতে "বনাম" প্রতিটি "জন্য"


200

আমি কেবল রুবির লুপগুলি সম্পর্কে একটি দ্রুত প্রশ্ন করেছি। কোনও সংগ্রহের মাধ্যমে পুনরাবৃত্তি করার এই দুটি পদ্ধতির মধ্যে কি পার্থক্য রয়েছে?

# way 1
@collection.each do |item|
  # do whatever
end

# way 2
for item in @collection
  # do whatever
end

কেবল ভাবছেন যে এগুলি কি ঠিক একই বা সম্ভবত যদি একটি সূক্ষ্ম পার্থক্য রয়েছে (সম্ভবত যখন @collectionশূন্য থাকে)।

উত্তর:


315

এই একমাত্র পার্থক্য:

প্রতিটি:

irb> [1,2,3].each { |x| }
  => [1, 2, 3]
irb> x
NameError: undefined local variable or method `x' for main:Object
    from (irb):2
    from :0

জন্য:

irb> for x in [1,2,3]; end
  => [1, 2, 3]
irb> x
  => 3

forলুপের সাথে, পুনরাবৃত্তকরণের পরিবর্তনশীলটি ব্লকটি শেষ হওয়ার পরেও বেঁচে থাকে। সঙ্গে eachলুপ, এটা যদি না তা ইতিমধ্যেই আগে লুপ শুরু একটি স্থানীয় পরিবর্তনশীল হিসাবে সংজ্ঞায়িত করা হয়, না।

এটি ব্যতীত, পদ্ধতির forজন্য কেবল সিনট্যাক্স চিনির ব্যবস্থা রয়েছে each

যখন @collectionহয় nilউভয় লুপ একটি ব্যতিক্রম নিক্ষেপ:

ব্যতিক্রম: অপরিজ্ঞাত স্থানীয় ভেরিয়েবল বা পদ্ধতি c @ সংগ্রহ "প্রধানের জন্য: অবজেক্ট


3
x কী ক্ষেত্রে উপযুক্ত কারণেই রয়েছে বা এই খারাপ নকশাটি রয়েছে: পি? আমার কাছে মনে হয় এটি অন্যান্য ভাষার সাথে তুলনা করে তুলনামূলক কম।
cyc115

3
@ cyc115 কারণে xদেহাবশেষের জন্য দৃশ্যকল্প সত্য যে (সাধারণভাবে বলতে) কিওয়ার্ড নতুন সুযোগ তৈরি করবেন না জন্য হয়েছে। যদি , যদি না , শুরু , জন্য , যখন , ইত্যাদি বর্তমান সুযোগ আছে এমন সমস্ত কাজ। #eachতবে একটি ব্লক গ্রহণ করে। ব্লক সর্বদা বর্তমান স্কোপের শীর্ষে তাদের নিজস্ব সুযোগ যুক্ত করে। এর অর্থ হ'ল ব্লকের নতুন ভেরিয়েবল ঘোষণা করা (সুতরাং একটি নতুন সুযোগ) ব্লকের বাইরে থেকে অ্যাক্সেসযোগ্য হবে না কারণ সেখানে অতিরিক্ত স্কোপ উপলব্ধ নেই।
3limin4t0r

43

একটি ভাল ব্যাখ্যার জন্য " লুপের দুর্দশাগুলি " দেখুন (ভেরিয়েবল স্কোপিং বিবেচনা করে একটি ছোট পার্থক্য রয়েছে)।

ব্যবহার eachকরা হয় আরো কথ্য বিবেচিত রুবি ব্যবহার।


@ জাচল্টা: অবহিত করার জন্য ধন্যবাদ আমি লিঙ্কটি সম্পাদনা করব আর্টিকেলের একটি ওয়েবআরচিভ.আর.আর।
ক্রিস্টোফিড

1
graysoftinc.com/early-steps/the-evils-of-the-for-loop নতুন লিঙ্ক, এখন জেজি 2 এর সাইটটি অনলাইনে ফিরে এসেছে।
pnomolos

30

আপনার প্রথম উদাহরণ,

@collection.each do |item|
  # do whatever
end

আরও মূর্খ । নির্মান লুপিং রুবি সমর্থন পছন্দ যদিও forএবং while, ব্লক সিনট্যাক্স সাধারণত পছন্দ করা হয়।

আর একটি সূক্ষ্ম পার্থক্য হ'ল আপনি কোনও forলুপের মধ্যে ঘোষিত যে কোনও ভেরিয়েবল লুপের বাইরে পাওয়া যাবে, অন্যদিকে পুনরাবৃত্তকারী ব্লকের মধ্যে থাকা কার্যকরভাবে ব্যক্তিগত।


whileএবং untilআসলে কিছু খুব কংক্রিট ব্যবহার রয়েছে যা প্রতিটির সাথে প্রতিস্থাপন করা যায় না যেমন উদাহরণস্বরূপ অনন্য মান উত্পন্ন করা বা আরপিএল এর জন্য।
সর্বোচ্চ

6

আরও একটি ভিন্ন ..

number = ["one", "two", "three"]
 => ["one", "two", "three"] 

loop1 = []
loop2 = []

number.each do |c|
  loop1 << Proc.new { puts c }
end
 => ["one", "two", "three"] 

for c in number
  loop2 << Proc.new { puts c }
end
 => ["one", "two", "three"] 

loop1[1].call
two
 => nil 

loop2[1].call
three
 => nil 

উত্স: http://paulphPLov.com/articles/enumerable-each-vs-for-loops-in-ruby

আরও পরিষ্কারের জন্য: http://www.ruby-forum.com/topic/179264#784884


2

দেখে মনে হচ্ছে কোনও পার্থক্য নেই, নীচে forব্যবহার করে each

$ irb
>> for x in nil
>> puts x
>> end
NoMethodError: undefined method `each' for nil:NilClass
    from (irb):1
>> nil.each {|x| puts x}
NoMethodError: undefined method `each' for nil:NilClass
    from (irb):4

বায়ার্ড যেমন বলেছেন, প্রত্যেকেই বেশি মূ .়। এটি আপনার কাছ থেকে আরও লুকায় এবং বিশেষ ভাষার বৈশিষ্ট্যগুলির প্রয়োজন হয় না। প্রতি টেলিমাচাসের মন্তব্য

for .. in .. লুপের সুযোগের বাইরে পুনরুক্তি স্থাপন করে

for a in [1,2]
  puts a
end

aলুপ শেষ হওয়ার পরে পাতার সংজ্ঞা দেওয়া হয়। যেখানে যেমন eachনা। যা ব্যবহারের পক্ষে অন্য কারণ each, কারণ অস্থায়ী পরিবর্তনশীল একটি স্বল্প সময়ের জীবনযাপন করে।


1
সেখানে হয় (yjerem, ChristopheD এবং Bayard, উল্লেখ হিসাবে) একটি ছোট পার্থক্য পরিবর্তনশীল সুযোগ বিষয়ে।
টেলিমাচাস

ভুল, নীচে forব্যবহার করে না each। অন্যান্য উত্তর দেখুন।
akuhn

@akuhn আরও স্পষ্টতার জন্য দয়া করে এই প্রশ্ন এবং এর দুটি চমৎকার উত্তর দেখুন।
সাগর পান্ড্যা

2

কখনও কখনও forএটি ব্যবহার না করে প্রায় অবিরতযোগ্য বাগের কারণ হতে পারে।

বোকা বোকা বানাবেন না, এটি আইডেম্যাটিক কোড বা স্টাইল সম্পর্কিত সমস্যা নয়। রুবির বাস্তবায়নে forগুরুতর ত্রুটি রয়েছে এবং এটি ব্যবহার করা উচিত নয়।

এখানে একটি উদাহরণ রয়েছে যেখানে forবাগটি প্রবর্তন করা হয়,

class Library
  def initialize
    @ary = []
  end
  def method_with_block(&block)
    @ary << block
  end
  def method_that_uses_these_blocks
    @ary.map(&:call)
  end
end

lib = Library.new

for n in %w{foo bar quz}
  lib.method_with_block { n }
end

puts lib.method_that_uses_these_blocks

ছাপে

quz
quz
quz

%w{foo bar quz}.each { |n| ... }প্রিন্ট ব্যবহার

foo
bar
quz

কেন?

একটি forলুপে ভেরিয়েবলটি nএকবার এবং শুধুমাত্র সংজ্ঞায়িত করা হয় এবং তারপরে সেই সংজ্ঞাটি সমস্ত পুনরাবৃত্তির জন্য ব্যবহৃত হয়। সুতরাং প্রতিটি ব্লক একই সাথে উল্লেখ করে nযার quzলুপ শেষ হওয়ার সাথে সাথে এর একটি মান রয়েছে । বাগ!

একটি eachলুপে nপ্রতিটি পুনরাবৃত্তির জন্য একটি তাজা ভেরিয়েবল সংজ্ঞায়িত করা হয়, উদাহরণস্বরূপ উপরে ভেরিয়েবলটি nতিনটি পৃথক সময় সংজ্ঞায়িত করা হয়। সুতরাং প্রতিটি ব্লক nসঠিক মান সহ একটি পৃথক উল্লেখ করে ।


0

আমি যতদূর জানি, ইন-ল্যাঙ্গুয়েজ নিয়ন্ত্রণ স্ট্রাকচারের পরিবর্তে ব্লক ব্যবহার করা আরও মূর্খবাদী।


0

আমি কেবল রুবির ইন লুপ সম্পর্কে একটি নির্দিষ্ট পয়েন্ট তৈরি করতে চাই। এটি অন্য ভাষার মতো নির্মাণের মতো মনে হতে পারে তবে এটি রুবির প্রতিটি লুপিং কনস্ট্রাক্টের মতোই একটি অভিব্যক্তি। প্রকৃতপক্ষে, জন্য প্রতিটি প্রতিটি পুনরাবৃত্তকারীর মতো গণ্য অবজেক্টের সাথে কাজ করে।

সংগ্রহটি পাসের জন্য যে কোনও বস্তু হতে পারে যার প্রতিটি পুনরুক্তি পদ্ধতি রয়েছে। অ্যারে এবং হ্যাশগুলি প্রতিটি পদ্ধতিকে সংজ্ঞায়িত করে এবং অন্যান্য অনেক রুবি বস্তুও তা করে। For / in লুপ নির্দিষ্ট বস্তুর প্রতিটি পদ্ধতিকে কল করে। যেটি পুনরাবৃত্তকারী মান দেয়, লুপের জন্য প্রতিটি মান (বা মানগুলির প্রতিটি সেট) নির্দিষ্ট ভেরিয়েবল (বা ভেরিয়েবল )গুলিতে নির্ধারিত করে এবং তারপরে শরীরে কোডটি কার্যকর করে।

এটি একটি নির্বোধ উদাহরণ, তবে বিন্দুটি চিত্রিত করে যে ইন ইন লুপটি যে কোনও একটি অবজেক্টের সাথে কাজ করে যার প্রতিটি পদ্ধতি রয়েছে, যেমন প্রতিটি পুনরুক্তিকারী কীভাবে করে:

class Apple
  TYPES = %w(red green yellow)
  def each
    yield TYPES.pop until TYPES.empty?
  end
end

a = Apple.new
for i in a do
  puts i
end
yellow
green
red
=> nil

এবং এখন প্রতিটি পুনরুক্তি:

a = Apple.new
a.each do |i|
  puts i
end
yellow
green
red
=> nil

আপনি দেখতে পাচ্ছেন, উভয়ই প্রতিটি পদ্ধতিতে প্রতিক্রিয়া জানাচ্ছে যা ব্লকে ফিরে মান দেয়। এখানে সবাই যেমন বলেছে, প্রতিটি লৌকিকটি অবশ্যই ইন-লুপের উপরে ব্যবহার করা ভাল। আমি কেবল বাড়িতে এই পয়েন্টটি চালাতে চেয়েছিলাম যে ইন লুপটির জন্য যাদুকর কিছুই নেই। এটি এমন একটি অভিব্যক্তি যা কোনও সংগ্রহের প্রতিটি পদ্ধতিকে অনুরোধ করে এবং তারপরে এটি কোডের ব্লকে পাস করে। সুতরাং, এটি খুব বিরল ক্ষেত্রে আপনার প্রয়োজন হবে the প্রতিটি পুনরুক্তি প্রায় সর্বদা ব্যবহার করুন (ব্লক স্কোপের অতিরিক্ত সুবিধা সহ)।


0
(1..4).each { |i| 


  a = 9 if i==3

  puts a 


}
#nil
#nil
#9
#nil

for i in 1..4

  a = 9 if i==3

  puts a

end
#nil
#nil
#9
#9

'ফর' লুপে, স্থানীয় ভেরিয়েবল প্রতিটি লুপের পরেও বেঁচে থাকে। 'প্রতিটি' লুপে, প্রতিটি লুপের পরে স্থানীয় পরিবর্তনশীল সতেজ হয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.