কম্পিউটার টিউটোরিয়াল

রুবির DATA এবং __END__ ব্যবহার করুন: কোড এবং ডেটা সিমলেসলি এম্বেড করতে

আপনি কি জানতেন রুবি একটি উপায় প্রদান করে যাতে আপনার স্ক্রিপ্ট তার নিজস্ব সোর্স ফাইলকে ডেটার সোর্স হিসেবে ব্যবহার করতে পারে? এটা একটি নীট ট্রিক যা আপনাকে কিছুটা সময় বাঁচাতে পারে वन-অফ স্ক্রিপ্ট এবং প্রুফ অফ কনসেপ্ট লিখার সময়। চলুন দেখি!

DATA এবং __END__

নিচের উদাহরণে, আমি একটি ফানি কীওয়ার্ড __END__ ব্যবহার করছি। __END__-এর নিচের সবকিছু রুবি ইন্টারপ্রেটার ইগনোর করবে। কিন্তু আরও আকর্ষণীয়ভাবে, রুবি আপনাকে একটি IO অবজেক্ট দেয় DATA নামে, যা আপনাকে __END__-এর নিচের সবকিছু পড়তে দেয় ঠিক যেকোনো অন্য ফাইলের মতো।

নিচের উদাহরণে, আমরা প্রতিটি লাইন ওভার ইটারেট করি এবং প্রিন্ট করি।

DATA.each_line do |line|
  puts line
end
__END__
Doom
Quake
Diablo

এই টেকনিকের আমার ফেভারেট প্র্যাকটিক্যাল উদাহরণ ব্যবহার করে DATA একটি ERB টেমপ্লেট ধারণ করতে। এটি YAML, CSV ইত্যাদির সাথে ও কাজ করে।

require 'erb'
time = Time.now
renderer = ERB.new(DATA.read)
puts renderer.result()
__END__
The current time is <%= time %>.

আপনি আসলে DATA ব্যবহার করে __END__ কীওয়ার্ডের উপরের কন্টেন্টও পড়তে পারেন। এটা কারণ DATA আসলে পুরো সোর্স ফাইলের একটি পয়েন্টার, __END__ কীওয়ার্ডে ফাস্ট-ফরওয়ার্ডেড। আপনি এটা দেখতে পারেন যদি আপনি IO অবজেক্টটি রিওয়াইন্ড করুন প্রিন্ট করার আগে। নিচের উদাহরণ পুরো সোর্স ফাইল প্রিন্ট করে।

DATA.rewind
puts DATA.read # পুরো সোর্স ফাইল প্রিন্ট করে
__END__
meh

দ্যা মাল্টিপল-ফাইল দিলেমা

এই টেকনিকের একটি বড় ডাউনসাইড হলো এটা শুধু কাজ করে যদি আপনার স্ক্রিপ্ট একটি সিংগল সোর্স ফাইলে ফিট হয়, এবং আপনি সেটা সরাসরি রান করেন, ইনক্লুড করার বদলে।

নিচের উদাহরণে, আমার দুটি ফাইল আছে, প্রতিটির নিজস্ব __END__ সেকশন। কিন্তু শুধু একটি DATA গ্লোবাল হতে পারে। তাই দ্বিতীয় ফাইলের __END__ সেকশন অ্যাক্সেসযোগ্য নয়।

# first.rb
require "./second"
puts "First file\n----------------------"
puts DATA.read
print_second_data()
__END__
First end clause
# second.rb
def print_second_data
  puts "Second file\n----------------------"
  puts DATA.read # কিছুই আউটপুট করবে না, কারণ first.rb পুরো ফাইল পড়েছে
end
__END__
Second end clause
snhorne ~/tmp $ ruby first.rb
First file
----------------------
First end clause
Second file
----------------------

মাল্টিপল ফাইলের জন্য ওয়ার্কঅরাউন্ড

সিন্যাট্রার (Sinatra) একটি চমৎকার ফিচার আছে যা আপনাকে একাধিক ইনলাইন টেমপ্লেট যোগ করতে দেয় আপনার অ্যাপসে __END__ স্টেটমেন্টের পরে সেগুলো রাখে। এটা দেখতে এরকম:

# এই কোডটি সিন্যাট্রা ডক্স থেকে https://www.sinatrarb.com/intro.html
require 'sinatra'
get '/' do
  haml :index
end
__END__
@@ layout
%html
  = yield
@@ index
%div.title Hello world.

কিন্তু সিন্যাট্রা ঠিক কীভাবে এটা করে? আমাদের অ্যাপটি সম্ভবত র‍্যাক দ্বারা লোড হবে। আপনি প্রোডাকশনে ruby myapp.rb রান করবেন না! তারা নিশ্চিতভাবেই DATA মাল্টিপল ফাইলসহ ব্যবহার করার উপায় বের করল।

যদি আপনি সিন্যাট্রা সোর্স একটু খনন করেন, আপনি দেখবেন তারা একটু চিটিং করছে। তারা DATA ব্যবহার করছে না। বদলে তারা কিছুটা নিচের কোডের মতো করছে।

# আমি প্যারাফ্রেজ করছি। মূলটি দেখুন https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L1284
app, data = File.read(__FILE__).split(/^__END__$/, 2)

এটা একটু বেশি জটিল, কারণ তারা __FILE__ পড়তে চায় না। এটা শুধু sinatra/base.rb ফাইল হবে। বরং তারা সেই ফাইলের কন্টেন্ট চায় যেটি একটি ফাংশন ইনভোক করেছে। তারা সেটা caller রেজাল্ট পার্স করে পায়।

caller ফাংশন আপনাকে বলবে বর্তমানে চলমান ফাংশন কোথায় ইনভোক করা হয়েছে। এখানে একটি কুইক উদাহরণ:

def some_method
  puts caller
end
some_method
# => caller.rb:5:in `
'

এখন ফাইলনেম সেটা থেকে বের করা এবং সেটার জন্য DATA-এর সমতুল্য কিছু এক্সট্রাক্ট করা একটা সিম্পল বিষয়।

def get_caller_data
  puts File.read(caller.first.split(":").first).split("__END__", 2).last
end

ভালো কাজের জন্য ব্যবহার করুন, খারাপ কাজের জন্য না

আশা করি স్పষ্ট যে এই ট্রিকগুলো এমন কিছু নয় যা আপনি প্রতিদিন ব্যবহার করবেন। এগুলো ক্লিন, মেইনটেইনযোগ্য বড় কোড বেসের জন্য সাবসিটেবল নয়।

তবে কখনো কখনো আপনার কিছু কুইক অ্যান্ড ডার্টি কিছু দরকার পড়ে, হয় একটি वन-অফ ইউটিলিটি স্ক্রিপ্টের জন্য বা প্রুফ অফ কনসেপ্টের জন্য। সেক্ষেত্রে, DATA এবং __END__ খুব উপকারী হতে পারে।

  1. রুবিতে লেজি এনিউমেরেটর মাস্টারিং: বিশাল ফাইল দক্ষতার সাথে প্রসেস করুন

  2. রুবি লগিং মাস্টারি: Logger এবং Lograge-এ এক্সপার্ট গাইড

  3. রুবিতে ফাইল পড়া এবং লেখা: একটি স্টেপ-বাই-স্টেপ গাইড

  4. উইন্ডোজ ১০-এ File History দিয়ে ফাইল সेफগার্ড ও রিস্টোর: সম্পূর্ণ গাইড