পদ্ধতিগুলির ভিতরে কী কী পদ্ধতি থাকা সম্ভব?


89

আমি একটি পদ্ধতির ভিতরে একটি পদ্ধতি আছে। অভ্যন্তরীণ পদ্ধতিটি চলমান একটি চলক লুপের উপর নির্ভর করে। যে একটি খারাপ ধারণা?


4
আপনি কি কোডের নমুনা ভাগ করতে পারেন বা আপনি যা করার চেষ্টা করছেন তার কমপক্ষে একটি যৌক্তিক সমতুল্য।
অ্যারন স্ক্রাগস

উত্তর:


165

আপডেট: যেহেতু এই উত্তরটি ইদানীং কিছুটা আগ্রহ অর্জন করেছে বলে মনে হচ্ছে, আমি এখানে উল্লেখ করতে চেয়েছিলাম যে রুবি ইস্যু ট্র্যাকার নিয়ে এখানে আলোচনা করা বৈশিষ্ট্যটি মুছে ফেলার জন্য আলোচনা চলছে , যথা একটি পদ্ধতির শরীরে অভ্যন্তরীণ সংজ্ঞা থাকা নিষেধ


না, রুবির নেস্টেড পদ্ধতি নেই।

আপনি এর মতো কিছু করতে পারেন:

class Test1
  def meth1
    def meth2
      puts "Yay"
    end
    meth2
  end
end

Test1.new.meth1

কিন্তু যে না একটি নেস্টেড পদ্ধতি। আমি আবার বলছি: রুবি নেই নেস্টেড পদ্ধতি।

এটি কী, একটি গতিশীল পদ্ধতির সংজ্ঞা। আপনি যখন চালনা করবেন তখন meth1এর বডি meth1কার্যকর করা হবে। শরীরটি কেবল নামের একটি পদ্ধতিটি সংজ্ঞায়িত করতেই ঘটে meth2, এজন্য একবার চালানোর পরে meth1, আপনি কল করতে পারেন meth2

তবে কোথায় meth2সংজ্ঞায়িত হয়? ঠিক আছে, এটি অবশ্যই কোনও নেস্টেড পদ্ধতি হিসাবে সংজ্ঞায়িত করা হয়নি , যেহেতু রুবিতে কোনও নেস্টেড পদ্ধতি নেই । এটি একটি উদাহরণ পদ্ধতি হিসাবে সংজ্ঞায়িত Test1:

Test1.new.meth2
# Yay

এছাড়াও, আপনি প্রতিবার দৌড়ানোর সময় এটি স্পষ্টতই সংজ্ঞায়িত হবে meth1:

Test1.new.meth1
# Yay

Test1.new.meth1
# test1.rb:3: warning: method redefined; discarding old meth2
# test1.rb:3: warning: previous definition of meth2 was here
# Yay

সংক্ষেপে: না, রুবি নেস্টেড পদ্ধতিগুলিকে সমর্থন করে না

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


আপডেট অবিরত: পরবর্তী পর্যায়ে, তারপরে, এই সিনট্যাক্সটি রুবীতে নেস্টেড পদ্ধতি যুক্ত করার জন্য পুনরায় ব্যবহার করা যেতে পারে, যা আমার বর্ণিত পদ্ধতিতে আচরণ করবে: এগুলি তাদের ধারণকৃত পদ্ধতিতে বিস্তৃত হবে, অর্থাত্ তাদের উপস্থিত পদ্ধতির বাইরে অদৃশ্য এবং অ্যাক্সেসযোগ্য would শরীর। এবং সম্ভবত, তাদের রয়েছে তাদের ধারণকৃত পদ্ধতির লেক্সিকাল স্কোপে অ্যাক্সেস। যাইহোক, আপনি উপরে উল্লিখিত আলোচনাটি যদি আপনি পড়ে থাকেন তবে আপনি পর্যবেক্ষণ করতে পারবেন ম্যাটজ নেস্টেড পদ্ধতির বিরুদ্ধে (তবে এখনও নেস্টেড পদ্ধতির সংজ্ঞাগুলি অপসারণের জন্য) against


6
আপনি ডিআরওয়াইনেসের জন্য কোনও পদ্ধতিতে ক্লোজার লাম্বদা কীভাবে তৈরি করবেন বা পুনরাবৃত্তি চালাতে পারবেন তাও আপনি দেখিয়ে দিতে পারেন।
ফ্রোগজ

119
আমি এমন অনুভূতি পাচ্ছি যে রুবির হয়ত নেস্টেড পদ্ধতি নাও থাকতে পারে।
মার্ক থমাস

16
@ মার্ক থমাস: আমি কি উল্লেখ করতে ভুলে গেছি যে রুবি নেস্টেড পদ্ধতিতে নেই? :-) সিরিয়াসলি: সময় আমি এই উত্তর লিখেছে এ ইতিমধ্যেই তিন উত্তর, প্রতিটি যার মধ্যে দাবি রুবি যে ছিল না নেস্টেড পদ্ধতি আছে। এই উত্তরগুলির মধ্যে কিছুগুলির এমনকি সম্পূর্ণরূপে ভুল হওয়া সত্ত্বেও তা উপবিষ্ট ছিল। একটি এমনকি ভুল হওয়া সত্ত্বেও, আবারও ওপি দ্বারা গৃহীত হয়েছিল। কোড স্নিপেট যা উত্তরটি প্রমাণ করতে ব্যবহার করে যে রুবি নেস্টেড পদ্ধতিগুলিকে সমর্থন করে, বাস্তবে বিপরীতটি প্রমাণ করে, তবে আপাতদৃষ্টিতে upvoters বা ওপি আসলেই চেক করতে বিরক্ত করেনি। সুতরাং, আমি প্রতিটি ভুলটির জন্য একটি সঠিক উত্তর দিয়েছি। :-)
জার্গ ডব্লু মিটাগ

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

4
কোনও পদ্ধতি নেই, আপনার কোডটি দ্য ম্যাট্রিক্স
বিবোজোতে

13

আসলে এটা সম্ভব। আপনি এর জন্য প্রস / ল্যাম্বদা ব্যবহার করতে পারেন।

def test(value)
  inner = ->() {
    value * value
  }
  inner.call()
end

4
আপনি ভুল নন, তবে আপনার উত্তরটি নেস্টেড পদ্ধতিগুলি অর্জনের সমাধান হিসাবে শব্দযুক্ত। যখন বাস্তবে আপনি কেবল প্রক্স ব্যবহার করেন যা কোনও পদ্ধতি নয়। "নেস্টেড পদ্ধতিগুলি" সমাধান করার দাবি করার বাইরে এটির উত্তম উত্তর
ব্র্যান্ডন বাক

5

না, না, রুবিতে নেস্টেড পদ্ধতি রয়েছে। এটা যাচাই কর:

def outer_method(arg)
    outer_variable = "y"
    inner_method = lambda {
      puts arg
      puts outer_variable
    }
    inner_method[]
end

outer_method "x" # prints "x", "y"

9
অভ্যন্তরীণ_মোথোড কোনও পদ্ধতি নয়, এটি একটি ফাংশন / ল্যাম্বদা / প্রোক। কোনও শ্রেণীর সাথে সম্পর্কিত কোনও উদাহরণ নেই তাই এটি কোনও পদ্ধতি নয়।
সামি সামহুরী

2

আপনি এরকম কিছু করতে পারেন

module Methods
  define_method :outer do 
    outer_var = 1
    define_method :inner do
      puts "defining inner"
      inner_var = outer_var +1
    end
    outer_var
  end
  extend self
end

Methods.outer 
#=> defining inner
#=> 1
Methods.inner 
#=> 2

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


2

রুবি উপায়টি হ'ল বিভ্রান্তিকর হ্যাকগুলির সাথে এটি জাল করা যা কিছু ব্যবহারকারীদের ভাবতে থাকবে "কীভাবে এই কাজ এমনকি কীভাবে হয়?", যখন কম আগ্রহী জিনিসটি ব্যবহার করার জন্য প্রয়োজনীয় সিনট্যাক্সটি কেবল মুখস্ত করে ফেলবে। আপনি যদি কখনও রেকে বা রেল ব্যবহার করেন তবে আপনি এই জাতীয় জিনিসটি দেখেছেন।

এখানে যেমন একটি হ্যাক:

def mlet(name,func)
  my_class = (Class.new do
                def initialize(name,func)
                  @name=name
                  @func=func
                end
                def method_missing(methname, *args)
                  puts "method_missing called on #{methname}"
                  if methname == @name
                    puts "Calling function #{@func}"
                    @func.call(*args)
                  else
                    raise NoMethodError.new "Undefined method `#{methname}' in mlet"
                  end
                end
              end)
  yield my_class.new(name,func)
end

এটি কী করে তা একটি শীর্ষ-স্তরের পদ্ধতি সংজ্ঞায়িত করা হয় যা একটি শ্রেণী তৈরি করে এবং এটি একটি ব্লকে পাস করে। শ্রেণিটি method_missingভান করার জন্য ব্যবহার করে যে এটি আপনার চয়ন করা নামের সাথে একটি পদ্ধতি রয়েছে। এটি আপনাকে সরবরাহ করা ল্যাম্বদা কল করে পদ্ধতিটি "প্রয়োগ" করে। এক-অক্ষরের নামের সাথে অবজেক্টটির নামকরণ করে আপনি অতিরিক্ত টাইপিংয়ের পরিমাণটি হ্রাস করতে পারেন যা এটি প্রয়োজন (যা রেইলগুলি একই কাজ করে schema.rb)। mletকমন লিস্প ফর্মের নামানুসারে নামকরণ করা হয়েছে flet, যেখানে f"ফাংশন" এর mঅর্থ দাঁড়ায় "পদ্ধতি"।

আপনি এটি এর মতো ব্যবহার করুন:

def outer
   mlet :inner, ->(x) { x*2 } do |c|
     c.inner 12
   end
end

একই রকম বৈপরীত্য তৈরি করা সম্ভব যা অতিরিক্ত বাসা ছাড়াই একাধিক অভ্যন্তরীণ ফাংশন সংজ্ঞায়িত করতে দেয়, তবে এর জন্য রাক বা আরএসপেকের প্রয়োগে আপনি যে ধরণের সন্ধান করতে পারেন তার একটি এমনকি কৃপণ হ্যাক প্রয়োজন। আরএসপেকের let!কাজগুলি কীভাবে আপনাকে এইরকম ভয়াবহ জঘন্যতা তৈরি করতে সক্ষম হতে পারে তা সন্ধান করা।


-3

:-D

রুবির পদ্ধতিতে নেস্ট রয়েছে, কেবল তারা যা করেন তা আপনি করেন না

1.9.3p484 :001 > def kme; 'kme'; def foo; 'foo'; end; end              
 => nil 
1.9.3p484 :003 >   self.methods.include? :kme
 => true 
1.9.3p484 :004 > self.methods.include? :foo
 => false 
1.9.3p484 :005 > kme
 => nil 
1.9.3p484 :006 > self.methods.include? :foo
 => true 
1.9.3p484 :007 > foo
 => "foo" 

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