অ্যারে ওয়ারেট করলে, একটি শর্টকাট আমি বারবার ব্যবহার করি। সেটি হল `&:` ট্রিক, যাকে "ampersand colon" বা "pretzel colon" বলা হয়। আপনি যদি এর সাথে পরিচিত না হন, তবে নিচে দেখুন কিভাবে কাজ করে:
words = ["would", "you", "like", "to", "play", "a", "game?"] # এটি... words.map &:length # ..এর সমতুল্য: words.map { |w| w.length } হালবেলা পর্যন্ত আমি মনে করতাম `&:` সিন্ট্যাক্স একটি অপারেটর। কিন্তু সেটি নয়। এটি একটি চমৎকার হ্যাক যা ActiveSupport-এ শুরু হয়েছিল এবং রুবি ১.৮.৭-এ অফিশিয়াল ফিচার হয়ে ওঠে।
`&` অপারেটর
AND লজিক অপারেশনের পাশাপাশি, রুবিতে `&` ক্যারেক্টারের আরেকটি ব্যবহার রয়েছে। যখন মেথড আর্গুমেন্টের শুরুতে এটি যোগ করা হয়, তবে এটি তার অপারেন্ডে `to_proc` কল করে এবং ব্লক হিসেবে পাস করে। এটি শুনতে জটিল, কিন্তু উদাহরণ দেখলে সহজ হবে:
def my_method(&block) block.call end class Greeter def self.to_proc Proc.new { "hello" } end end my_method(&Greeter) # "hello" রিটার্ন করে Symbol#to_proc
আপনি যেকোনো অবজেক্টে `to_proc` মেথড যোগ করতে পারেন, Symbol-এও। রুবি ঠিক इसी কাজটি করে `&:` শর্টকাটের জন্য। এটি দেখতে কিছু এইরকম:
class Symbol def to_proc Proc.new do |item| item.send self end end end ক্লিয়ার হয়েছে? গুরুত্বপূর্ণ অংশ হলো `item.send(self)`। এখানে `self` সিম্বলকে রেফার করে।
সবকुछ একসাথে
`each` এবং `map` এর মতো Enumerable মেথডগুলো ব্লক এক্সেপ্ট করে। প্রতিটি আইটেমের জন্য সেগুলো ব্লকে কল করে এবং আইটেমের রেফারেন্স পাস করে। এখানে ব্লক তৈরি হয় সিম্বলের `to_proc` কল করে।
# &:name একটি Proc-এ ইভ্যালুয়েট হয়, যা item.send(:name) করে items.map(&:name) মজার বিষয় হলো `map`-কে এই সব বিষয়ে কিছুই मालूम নেই! মূল কাজটি করছে `:name` সিম্বল। এটি অবশ্যই চমৎকার... почти খুব চমৎকার। কিন্তু এটি রুবির স্ট্যান্ডার্ড লাইব্রেরির অংশ বছরের পর বছর ধরে, এবং এত সুবিধাজনক যে আমি এখনও ব্যবহার করা বন্ধ করব না। :)