আমি একটি পদ্ধতির ভিতরে একটি পদ্ধতি আছে। অভ্যন্তরীণ পদ্ধতিটি চলমান একটি চলক লুপের উপর নির্ভর করে। যে একটি খারাপ ধারণা?
উত্তর:
আপডেট: যেহেতু এই উত্তরটি ইদানীং কিছুটা আগ্রহ অর্জন করেছে বলে মনে হচ্ছে, আমি এখানে উল্লেখ করতে চেয়েছিলাম যে রুবি ইস্যু ট্র্যাকার নিয়ে এখানে আলোচনা করা বৈশিষ্ট্যটি মুছে ফেলার জন্য আলোচনা চলছে , যথা একটি পদ্ধতির শরীরে অভ্যন্তরীণ সংজ্ঞা থাকা নিষেধ ।
না, রুবির নেস্টেড পদ্ধতি নেই।
আপনি এর মতো কিছু করতে পারেন:
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
আসলে এটা সম্ভব। আপনি এর জন্য প্রস / ল্যাম্বদা ব্যবহার করতে পারেন।
def test(value)
inner = ->() {
value * value
}
inner.call()
end
না, না, রুবিতে নেস্টেড পদ্ধতি রয়েছে। এটা যাচাই কর:
def outer_method(arg)
outer_variable = "y"
inner_method = lambda {
puts arg
puts outer_variable
}
inner_method[]
end
outer_method "x" # prints "x", "y"
আপনি এরকম কিছু করতে পারেন
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
করা হবে তখনই নতুন সংজ্ঞা দেওয়া হয়েছে । আপনি যদি এই আচরণটি চান, এবং আপনি মাঝে মাঝে করতে পারেন তবে এটি এটি পাওয়ার একটি ভাল উপায়।
রুবি উপায়টি হ'ল বিভ্রান্তিকর হ্যাকগুলির সাথে এটি জাল করা যা কিছু ব্যবহারকারীদের ভাবতে থাকবে "কীভাবে এই কাজ এমনকি কীভাবে হয়?", যখন কম আগ্রহী জিনিসটি ব্যবহার করার জন্য প্রয়োজনীয় সিনট্যাক্সটি কেবল মুখস্ত করে ফেলবে। আপনি যদি কখনও রেকে বা রেল ব্যবহার করেন তবে আপনি এই জাতীয় জিনিসটি দেখেছেন।
এখানে যেমন একটি হ্যাক:
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!
কাজগুলি কীভাবে আপনাকে এইরকম ভয়াবহ জঘন্যতা তৈরি করতে সক্ষম হতে পারে তা সন্ধান করা।
:-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"