ruby table Lambbda ব্যবহার করার সময়, Proc.new ব্যবহার করার সময়?




html tags pdf (12)

সংক্ষিপ্ত উত্তরঃ কি return আসে তা হল: লাম্বা নিজেই ফিরে আসে, এবং নিজের থেকে প্রত্যাবর্তন করে এবং ফাংশন যা এটি বলে।

আপনি প্রতিটি ব্যবহার করতে চান কেন কম স্পষ্ট কি। Lambda আমরা কি একটি কার্যকরী প্রোগ্রামিং অর্থে জিনিস করা উচিত আশা করি। বর্তমান সুযোগ স্বয়ংক্রিয়ভাবে আবদ্ধ সঙ্গে এটি মূলত একটি বেনামী পদ্ধতি। দুইটি, লাম্বা সম্ভবত আপনি ব্যবহার করা উচিত।

অন্যদিকে, প্রসিকিউটটি ভাষাটি বাস্তবায়নের জন্য সত্যিই দরকারী। উদাহরণস্বরূপ আপনি তাদের সাথে "if" বিবৃতি বা "জন্য" loops প্রয়োগ করতে পারেন। Proc তে পাওয়া যে কোনও রিটার্নটি কেবলমাত্র "if" স্টেটমেন্টটি নয়, এটি বলা পদ্ধতি থেকে প্রত্যাবর্তন করবে। ভাষা কিভাবে কাজ করে, কিভাবে "if" বিবৃতি কাজ করে, তাই আমার অনুমান রুবি এটি কভারের অধীনে ব্যবহার করে এবং তারা তা প্রকাশ করে কারণ এটি কার্যকর বলে মনে হয়।

যদি আপনি নতুন ভাষা গঠন যেমন loops, যদি-else গঠন, ইত্যাদি তৈরি করেন তবে আপনাকে কেবল এটিই প্রয়োজন হবে।

রুবি 1.8 তে, একদিকে proc / lambda এবং অন্যদিকে Proc.new মধ্যে সূক্ষ্ম পার্থক্য রয়েছে।

  • ঐ পার্থক্য কি?
  • কোনটি বেছে নিতে হবে তা নির্ধারণ করার জন্য আপনি নির্দেশিকাগুলি দিতে পারেন?
  • রুবি 1.9, প্রস এবং লাম্বাদা ভিন্ন। চুক্তিটি কি ছিল?

Lambda অন্যান্য ভাষার মত প্রত্যাশিত হিসাবে কাজ করে।

তারযুক্ত Proc.new বিস্ময়কর এবং বিভ্রান্তিকর।

Proc.new দ্বারা তৈরি proc মধ্যে return বিবৃতি শুধুমাত্র নিজেই থেকে নিয়ন্ত্রণ ফিরে না শুধুমাত্র, কিন্তু এটি বন্ধ enclosing পদ্ধতি থেকে

def some_method
  myproc = Proc.new {return "End."}
  myproc.call

  # Any code below will not get executed!
  # ...
end

আপনি Proc.new পদ্ধতিতে প্রবেশ করতে পারবেন। কিন্তু Proc.new একটি বস্তু তৈরি করে, যখন ব্লক একটি বস্তুর অংশ

এবং Lambda এবং Proc.new মধ্যে অন্য পার্থক্য আছে, যা তাদের (ভুল) আর্গুমেন্ট পরিচালনা করা হয়। Lambda এটি সম্পর্কে অভিযোগ, Proc.new অতিরিক্ত আর্গুমেন্ট উপেক্ষা বা বিবেচনা হিসাবে Proc.new অনুপস্থিত বিবেচনা।

irb(main):021:0> l = -> (x) { x.to_s }
=> #<Proc:[email protected](irb):21 (lambda)>
irb(main):022:0> p = Proc.new { |x| x.to_s}
=> #<Proc:[email protected](irb):22>
irb(main):025:0> l.call
ArgumentError: wrong number of arguments (0 for 1)
        from (irb):21:in `block in irb_binding'
        from (irb):25:in `call'
        from (irb):25
        from /usr/bin/irb:11:in `<main>'
irb(main):026:0> p.call
=> ""
irb(main):049:0> l.call 1, 2
ArgumentError: wrong number of arguments (2 for 1)
        from (irb):47:in `block in irb_binding'
        from (irb):49:in `call'
        from (irb):49
        from /usr/bin/irb:11:in `<main>'
irb(main):050:0> p.call 1, 2
=> "1"

Proc.new , প্রোটি রুবি 1.8 তে একটি ল্যাম্বা তৈরি করে, রুবি 1.9+ এ প্র্যাকটিভের মত আচরণ করে যা সত্যিই বিভ্রান্তিকর।


রবি ব্লকগুলি বোঝা, রবার্ট সোসিনস্কি দ্বারা প্রসেস এবং ল্যামডাসগুলি পরিষ্কারভাবে এই প্রোগ্রামিং ধারণাগুলি ব্যাখ্যা করে এবং উদাহরণ কোড সহ ব্যাখ্যাগুলিকে আরও শক্তিশালী করে। পদ্ধতি বস্তু সম্পর্কিত এবং পাশাপাশি আচ্ছাদিত হয়।


ইহা যে জোরপূর্বক আবদ্ধ পদ্ধতি থেকে একটি পিআর রিটার্নে ফেরত দেওয়া হয় তার অর্থ জোরদার করা, অর্থাৎ পদ্ধতি যেখানে proc তৈরি করা হয়েছিল , পদ্ধতিটি যা proc বলা হয় না। এই procs বন্ধ সম্পত্তি একটি পরিণতি হয়। তাই নিম্নলিখিত কোড আউটপুট কিছুই:

def foo
  proc = Proc.new{return}
  foobar(proc)
  puts 'foo'
end

def foobar(proc)
  proc.call
  puts 'foobar'
end

foo

যদিও proc foobar সঞ্চালিত হয়, এটি foo তৈরি করা হয়েছিল এবং তাই foobar কেবল foobar foo প্রস্থান করে। চার্লস ক্যালডওয়েল উপরে লিখেছেন, এটি একটি GOTO এটি অনুভব করেছে। আমার মতে, তার ব্ল্যাকিক্যাল প্রেক্ষাপটে মৃত্যুদন্ড কার্যকর করা একটি ব্লকের মধ্যে return উত্তম, কিন্তু ভিন্ন প্রেক্ষাপটে কার্যকর করা একটি প্রক্রিয়ায় ব্যবহৃত হয় তখন এটি খুব কম স্বজ্ঞাত।


রবিতে রবিতে ব্লক, লাম্বডা এবং প্রসেস কীভাবে কাজ করে, সে সম্পর্কে রবিতে ক্লোজারগুলি ভাল ধারণা।


Proc.new দিয়ে তৈরি lambda এবং procs দ্বারা তৈরি procs মধ্যে আরেকটি গুরুত্বপূর্ণ কিন্তু সূক্ষ্ম পার্থক্য হল তারা কীভাবে return বিবৃতি পরিচালনা করে:

  • একটি lambda -created proc মধ্যে, return বিবৃতি শুধুমাত্র proc থেকে নিজেই ফিরে
  • Proc.new -created proc তে, return স্টেটমেন্টটি একটু বেশি বিস্ময়কর: এটি কেবল proc থেকে নয়, Proc.new বন্ধ করে দেওয়ার পদ্ধতিও নিয়ন্ত্রণ করে!

এখানে lambda -created proc এর কর্ম return । এটি এমনভাবে আচরণ করে যা আপনি সম্ভবত আশা করেন:

def whowouldwin

  mylambda = lambda {return "Freddy"}
  mylambda.call

  # mylambda gets called and returns "Freddy", and execution
  # continues on the next line

  return "Jason"

end


whowouldwin
#=> "Jason"

এখন এখানে একটি Proc.new -created proc এর return একই জিনিস করছেন। আপনি রুবি একমাত্র বিস্ময়কর অতিপ্রাকৃত নীতি ভাঙ্গার ক্ষেত্রে সেগুলির একটি দেখতে চলেছেন:

def whowouldwin2

  myproc = Proc.new {return "Freddy"}
  myproc.call

  # myproc gets called and returns "Freddy", 
  # but also returns control from whowhouldwin2!
  # The line below *never* gets executed.

  return "Jason"

end


whowouldwin2         
#=> "Freddy"

ধন্যবাদ এই বিস্ময়কর আচরণ (পাশাপাশি কম টাইপিং), আমি Proc.new তৈরীর সময় Proc.new উপর lambda ব্যবহার করার পক্ষে পক্ষপাতিত্ব।


আমি সূক্ষ্ম পার্থক্য সম্পর্কে অনেক বলতে পারে না। যাইহোক, আমি নির্দেশ করতে পারি যে রুবি 1.9 এখন lambdas এবং ব্লক জন্য ঐচ্ছিক পরামিতি অনুমতি দেয়।

1.9 এর নিচে স্ট্যাবি লাম্বডসের নতুন সিনট্যাক্স এখানে রয়েছে:

stabby = ->(msg='inside the stabby lambda') { puts msg }

রুবি 1.8 যে সিনট্যাক্স ছিল না। ব্লক / lambdas সমর্থন ঐচ্ছিক উপায় উভয় না ঐচ্ছিক যুক্তি সমর্থন করে:

# under 1.8
l = lambda { |msg = 'inside the stabby lambda'|  puts msg }
SyntaxError: compile error
(irb):1: syntax error, unexpected '=', expecting tCOLON2 or '[' or '.'
l = lambda { |msg = 'inside the stabby lambda'|  puts msg }

রুবি 1.9, পুরানো সিনট্যাক্সের সাথে এমনকি ঐচ্ছিক আর্গুমেন্টগুলিকে সমর্থন করে:

l = lambda { |msg = 'inside the regular lambda'|  puts msg }
#=> #<Proc:[email protected](irb):1 (lambda)>
l.call
#=> inside the regular lambda
l.call('jeez')
#=> jeez

আপনি লিপার্ড বা লিনাক্সের জন্য রুবি 1.9 তৈরি করতে চান তবে এই নিবন্ধটি দেখুন (লজ্জাহীন স্ব প্রচার)।


অ্যাকর্ডিয়ন গায় এর প্রতিক্রিয়া জানানোর জন্য:

লক্ষ্য করুন যে Proc.new একটি ব্লক পাস করে একটি proc আউট তৈরি করে। আমি বিশ্বাস করি যে lambda {...} একটি অক্ষর যা একটি ব্লক পাস করার পরিবর্তে, আক্ষরিক হিসাবে একটি সাজানো হিসাবে বিশ্লেষণ করা হয়। একটি পদ্ধতি কল সংযুক্ত একটি ব্লকের ভিতর থেকে return পদ্ধতি থেকে ফিরে, ব্লক না, এবং Proc.new কেস খেলার এ একটি উদাহরণ।

(এই 1.8। আমি কিভাবে এই অনুবাদ 1.9 জানি না।)


আমি এই পৃষ্ঠাটি খুঁজে পেয়েছি যা দেখায় Proc.new এবং lambda মধ্যে পার্থক্য কি। পৃষ্ঠার মতে, একমাত্র পার্থক্য হল যে ল্যাম্বা এটি স্বীকার করে আর্গুমেন্টগুলির সংখ্যা সম্পর্কে কঠোর, এবং Proc.new অনুপস্থিত আর্গুমেন্টগুলিকে Proc.new রূপান্তরিত করে। এখানে একটি উদাহরণ আইআরবি অধিবেশন পার্থক্য illustrating হয়:

irb(main):001:0> l = lambda { |x, y| x + y }
=> #<Proc:[email protected](irb):1>
irb(main):002:0> p = Proc.new { |x, y| x + y }
=> #<Proc:[email protected](irb):2>
irb(main):003:0> l.call "hello", "world"
=> "helloworld"
irb(main):004:0> p.call "hello", "world"
=> "helloworld"
irb(main):005:0> l.call "hello"
ArgumentError: wrong number of arguments (1 for 2)
    from (irb):1
    from (irb):5:in `call'
    from (irb):5
    from :0
irb(main):006:0> p.call "hello"
TypeError: can't convert nil into String
    from (irb):2:in `+'
    from (irb):2
    from (irb):6:in `call'
    from (irb):6
    from :0

আপনি যদি বিশেষ করে ত্রুটির সহনশীল আচরণ চান তবে পৃষ্ঠাটি Lambda ব্যবহার করার পরামর্শ দেয়। আমি এই অনুভূতি সঙ্গে একমত। একটি ল্যাম্বা ব্যবহার করে আরও একটি সংক্ষিপ্ত সংক্ষেপে মনে হয়, এবং এইরকম একটি অস্পষ্ট পার্থক্যের সাথে, এটি গড় অবস্থায় ভাল পছন্দ বলে মনে হয়।

রুবি 1.9 হিসাবে, দুঃখিত, আমি 1.9 তে এখনো দেখিনি, কিন্তু আমি কল্পনা করি না যে তারা এটিকে সব পরিবর্তন করবে (এটির জন্য আমার শব্দটি গ্রহণ করবেন না, যদিও মনে হচ্ছে আপনি কিছু পরিবর্তন শুনেছেন, তাই আমি সম্ভবত সেখানে ভুল করছি)।


প্রক্রিয়াটি পুরোনো, কিন্তু ফিরতি শব্দগুলি আমার কাছে অত্যন্ত জটিল (অন্তত যখন আমি ভাষা শিখছি) কারণ:

  1. আপনি যদি proc ব্যবহার করেন তবে আপনি সম্ভবত কোনও কার্যকরী আদর্শ ব্যবহার করে সম্ভবত।
  2. প্রসেসটি বন্ধ করার সুযোগ (পূর্ববর্তী প্রতিক্রিয়াগুলি দেখুন) থেকে ফিরে যেতে পারে, যা মূলত একটি গোটো এবং প্রকৃতির অত্যন্ত কার্যকরী।

Lambda কার্যকরীভাবে নিরাপদ এবং সহজ কারণ সম্পর্কে - আমি সবসময় proc এর পরিবর্তে এটি ব্যবহার।


এটি দেখতে একটি ভাল উপায় হল যে lambdas তাদের নিজস্ব সুযোগে (যেমন এটি একটি পদ্ধতি কল ছিল) মৃত্যুদন্ড কার্যকর করা হয়, তবে প্রক্রিয়াগুলি কলিং পদ্ধতি সহ কার্যকর ইনলাইন হিসাবে দেখা যেতে পারে, অন্তত এটি ব্যবহার করার সিদ্ধান্ত নেওয়ার সিদ্ধান্ত অস্ত্রোপচারঅস্ত্রোপচার.


আরও ব্যাখ্যা প্রদান করতে:

Joey বলছেন যে Proc.new ফেরত আচরণ বিস্ময়কর। তবে যখন আপনি বিবেচনা করেন যে Proc.new একটি ব্লকের মতো আচরণ করে তবে এটি অবাক হওয়ার মতো নয় যে ঠিক কিভাবে ব্লকগুলি আচরণ করে। অন্যদিকে লাম্বাস পদ্ধতির মতো আচরণ করে।

এটি আসলে ব্যাখ্যা করে কেন প্রসেসগুলি নমনীয়তা (আর্গুমেন্ট সংখ্যা) যখন ল্যামডগুলি না হয় তখন নমনীয় কেন। ব্লকগুলি সরবরাহ করার জন্য তাদের সমস্ত আর্গুমেন্ট প্রয়োজন হয় না কিন্তু পদ্ধতিগুলি (ডিফল্ট সরবরাহ না করা পর্যন্ত) করতে হয়। Lambda Argument ডিফল্ট সরবরাহ করার সময় রুবি 1.8 তে একটি বিকল্প নেই, এটি এখন রুবি 1.9 বিকল্প ল্যাম্বা সিনট্যাক্স (ওয়েবমেট দ্বারা উল্লিখিত) সহ সমর্থিত:

concat = ->(a, b=2){ "#{a}#{b}" }
concat.call(4,5) # => "45"
concat.call(1)   # => "12"

এবং মাইকেল দে মারে (ওপি) রুবি 1.9 এর সমৃদ্ধির সাথে অভ্যাস এবং ল্যাম্বা একই আচরণ সম্পর্কে ভুল। আমি যাচাই করেছি যে তারা এখনও উপরে বর্ণিত 1.8 থেকে আচরণ বজায় রাখে।

break বিবৃতি আসলে প্রসেস বা lambdas হয় না অনেক জ্ঞান না। প্রসেসে, ব্রেক আপনি Proc.new থেকে ফিরে যা ইতিমধ্যে সম্পন্ন করা হয়েছে। এবং এটি একটি ল্যাম্বা থেকে ভাঙ্গার কোনো ধারনা দেয় না কারণ এটি মূলত একটি পদ্ধতি, এবং আপনি কোনও পদ্ধতির শীর্ষ স্তরের থেকে কখনও ভাঙ্গবেন না।

next , redo , এবং উভয় প্রসেস এবং lambdas মধ্যে একই আচরণ করা। যেখানে retry অনুমোদিত হয় না এবং একটি ব্যতিক্রম বাড়াতে হবে।

এবং অবশেষে, proc পদ্ধতিটি কখনই ব্যবহার করা উচিত নয় কারণ এটি অসঙ্গতিপূর্ণ এবং অপ্রত্যাশিত আচরণ। রুবি 1.8 তে আসলে এটি একটি লাম্বা ফেরত দেয়! রুবি 1.9 এ এটি স্থির করা হয়েছে এবং এটি একটি প্রসেস প্রদান করে। আপনি যদি Proc.new তৈরি করতে চান তবে Proc.new সাথে Proc.new

আরো তথ্যের জন্য, আমি অত্যন্তভাবে ও'রুলি'র রুবি প্রোগ্রামিং ভাষাটি সুপারিশ করি যা এই তথ্যের বেশিরভাগের জন্য আমার উৎস।





proc