কম্পিউটার

রুবিতে DATA এবং __END__ এর সাথে কোড এবং ডেটা মিশ্রিত করা

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

ডেটা এবং END

নীচের উদাহরণে, আমি __END__ নামে একটি মজার কীওয়ার্ড ব্যবহার করছি . নিচের সবকিছু __END__ রুবি দোভাষী দ্বারা উপেক্ষা করা হবে। কিন্তু আরো মজার বিষয় হল, রুবি আপনাকে DATA নামে একটি IO অবজেক্ট প্রদান করে , যা আপনাকে __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 # prints the entire source file

__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 # Won't output anything, since first.rb read the entire file
end

__END__

Second end clause

snhorne ~/tmp $ ruby first.rb
First file
----------------------
First end clause

Second file
----------------------

একাধিক ফাইলের জন্য একটি কাজ

সিনাত্রার একটি দুর্দান্ত বৈশিষ্ট্য রয়েছে যা আপনাকে __END__ এর পরে রেখে আপনার অ্যাপগুলিতে একাধিক ইনলাইন টেমপ্লেট যুক্ত করতে দেয়। বিবৃতি এটা এই মত দেখায়:

# This code is from the Sinatra docs at 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 ব্যবহার করছে না মোটেও পরিবর্তে তারা নীচের কোডের অনুরূপ কিছু করছে।

# I'm paraphrasing. See the original at https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L1284
app, data = File.read(__FILE__).split(/^__END__$/, 2)

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

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

def some_method
  puts caller
end

some_method # => caller.rb:5:in `<main>'

এখন সেখান থেকে ফাইলের নাম বের করে আনা এবং সেই ফাইলের জন্য ডেটার সমতুল্য কিছু বের করা খুবই সহজ ব্যাপার।

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

এটি ভালোর জন্য ব্যবহার করুন, মন্দ নয়

আশা করি এটা স্পষ্ট যে এই ধরনের কৌশলগুলি এমন কিছু নয় যা আপনি প্রতিদিন ব্যবহার করতে চান। তারা ঠিক পরিষ্কার, রক্ষণাবেক্ষণযোগ্য বড় কোড বেসের জন্য তৈরি করে না।

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


  1. রুবিতে বড় ফাইলগুলির সাথে কাজ করতে অলস গণনাকারী ব্যবহার করা

  2. Logger এবং Lograge সঙ্গে রুবি লগ ইন করুন

  3. রুবিতে ফাইলগুলি কীভাবে পড়তে এবং লিখতে হয় (উদাহরণ সহ)

  4. ফাইল ইতিহাস সহ উইন্ডোজ 10-এ ডেটা কীভাবে সংরক্ষণ এবং পুনরুদ্ধার করবেন