কম্পিউটার

উন্নত রুবি হ্যাশ কৌশল

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

কিন্তু আমি এখানে আপনাকে বলতে এসেছি যে নম্র রুবি হ্যাশের কিছু কৌশল রয়েছে। একটি বোবা কী-মান সিস্টেম হওয়া থেকে দূরে, হ্যাশ অবজেক্ট আপনাকে কিছু খুব আকর্ষণীয় এবং পরিশীলিত জিনিস করার ক্ষমতা দেয়।

যেকোন বস্তু একটি হ্যাশ কী হতে পারে

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

# Numbers can be hash keys
{1 => "one"}[1] # "one"

# So can the Ruby kernel
{Kernel => 1}[Kernel] # 1

# You can store values for specific classes
{Kernel => 1, String => 2}["hello world".class] # 2

# You can store values for booleans
{true => "verdad"}[1==1] # "verdad"

# You can even use complex arrays and even other hashes as hash keys
{[[1,0],[0,1]] => "identity matrix"}[[[1,0], [0,1]]] # "identity matrix"

এই বিকল্পগুলির মধ্যে কিছু অন্যদের চেয়ে বেশি দরকারী, কিন্তু সেগুলি সবই আপনার জন্য উপলব্ধ৷

ডিফল্ট মানটির উপর আপনার নিয়ন্ত্রণ আছে৷

ধরুন আপনার একটি হ্যাশ h={ a: 1 } আছে . আপনি যদি এমন একটি মান অ্যাক্সেস করার চেষ্টা করেন যা বিদ্যমান নেই - উদাহরণস্বরূপ   h[:x] - আপনি শূন্য পান। এর কারণ হল nil হল প্রতিটি হ্যাশের ডিফল্ট মান, যদি না আপনি অন্যথায় উল্লেখ করেন।

আপনি একটি নতুন হ্যাশ এর কনস্ট্রাক্টরে একটি আর্গুমেন্ট দিয়ে ডিফল্ট মান সেট করতে পারেন।

h = Hash.new("This attribute intentionally left blank")
h[:a] = 1
h[:a] # 1
h[:x] # "This attribute intentionally left blank"

ডাইনামিক ডিফল্ট মান

মনোযোগ দিন, কারণ এটি হল কৌশল যা অনুসরণ করে তার ভিত্তি।

আপনি যদি কনস্ট্রাক্টরে একটি ব্লক পাস করেন, আপনি প্রোগ্রামগতভাবে ডিফল্ট মান তৈরি করতে পারেন। নীচের উদাহরণে আমি ডিফল্ট মানটিতে একটি টাইমস্ট্যাম্প যুক্ত করেছি, যাতে আপনি দেখতে পারেন যে এটি গতিশীলভাবে তৈরি হচ্ছে৷

h = Hash.new { |hash, key| "#{key}: #{ Time.now.to_i }" }
h[:a] # "a: 1435682937"
h[:a] # "a: 1435682941"
h[:b] # "b: 1435682943"

এটি গুরুত্বপূর্ণ কারণ "ডিফল্ট মান" ব্লক একটি ডিফল্ট মান ফেরত ছাড়া অন্য কিছু করতে পারে৷

একটি হ্যাশ কী উপস্থিত না থাকলে একটি ব্যতিক্রম উত্থাপন করা

হ্যাশের প্রধান সমস্যাগুলির মধ্যে একটি হল তারা নীরবে ব্যর্থ হয়। আপনি ভুলবশত user[:phnoe] টাইপ করেছেন user[:phone] এর পরিবর্তে , এবং একটি ব্যতিক্রম উত্থাপনের পরিবর্তে, হ্যাশ শূন্য প্রদান করে। কিন্তু আপনি এই আচরণ পরিবর্তন করতে পারেন।

h = Hash.new { |hash, key| raise ArgumentError.new("No hash key: #{ key }") }
h[:a]=1
h[:a] # 1
h[:x] # raises ArgumentError: No hash key: x

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

দ্রষ্টব্য:আমি নতুন কোডে Hash.fetch এর জায়গায় এটি ব্যবহার করার পরামর্শ দিচ্ছি না। ডিবাগিং এবং রিফ্যাক্টরিংয়ের জন্য আপনার হাতা তৈরি করা এটি একটি আকর্ষণীয় কৌশল।

অলসভাবে তৈরি লুকআপ টেবিল

এই কৌশলটি একটি গণনার ফলাফল ক্যাশ করার জন্য দরকারী। কল্পনা করুন যে আপনাকে প্রচুর বর্গমূল গণনা করতে হবে। আপনি নীচের উদাহরণের মত একটি অলসভাবে জনবহুল লুকআপ টেবিল তৈরি করতে পারেন।

sqrt_lookup = Hash.new { |hash, key| hash[key] = Math.sqrt(key) }
sqrt_lookup[9] # 3.0
sqrt_lookup[7] # 2.6457513110645907
sqrt_lookup    # {9=>3.0, 7=>2.6457513110645907}

পুনরাবৃত্ত অলস লুকআপ টেবিল

ধরুন আপনার একটি পুনরাবৃত্ত ফাংশন আছে এবং আপনি প্রতিটি পুনরাবৃত্তির ফলাফল ক্যাশে করতে চান। উদাহরণ হিসেবে একটি ফ্যাক্টরিয়াল ক্যালকুলেশন নেওয়া যাক। "ফোর ফ্যাক্টরিয়াল", ওরফে "4!" "4x3x2x1" বলার আরেকটি উপায়। আপনি একটি হ্যাশ ব্যবহার করে পুনরাবৃত্তিমূলকভাবে এই বাস্তবায়ন করতে পারে. নীচের উদাহরণটি, যা আমি এই ব্লগ পোস্ট থেকে নিয়েছি তা সুন্দরভাবে প্রদর্শন করে:

factorial = Hash.new do |h,k| 
  if k > 1
    h[k] = h[k-1] * k
  else
    h[k] = 1
  end
end

factorial[4] # 24
factorial    # {1=>1, 2=>2, 3=>6, 4=>24}

শুরু করার পরে ডিফল্ট পরিবর্তন করা

একটি হ্যাশ তৈরি হওয়ার পরে আপনি ডিফল্ট মান নিয়ন্ত্রণ করতে পারেন। এটি করতে default ব্যবহার করুন এবং default_proc সেটার্স।

h={}
h[:a] # nil
h.default = "new default"
h[:a] # "new default"

h.default_proc = Proc.new { Time.now.to_i }
h[:a] # 1435684014

রুবি খুঁজুন:অলসভাবে অসীম নেস্টেড হ্যাশের একটি খেলা

শুধু মজা করার জন্য, আসুন এই সমস্ত দরকারী কৌশলগুলিকে একটি অত্যন্ত অকেজো উদাহরণে মোড়ানো যাক। সেই পুরানো টেক্সট-ভিত্তিক গেম অ্যাডভেঞ্চার মনে আছে? আসুন এটির সবচেয়ে বোকা সংস্করণ তৈরি করি৷

কল্পনা করুন আপনি একটি গুহায় আছেন। আপনি উত্তর, দক্ষিণ, পূর্ব বা পশ্চিম যেতে পারেন। এই পছন্দগুলির মধ্যে তিনটি আপনাকে গুহার একটি নতুন "রুমে" নিয়ে যাবে যেখানে আপনি অন্বেষণ চালিয়ে যান। কিন্তু একটি পছন্দ আপনাকে একটি "রুবি" এর দিকে নিয়ে যায়। তাই গেমটির নাম:"রুবি খুঁজুন।"

গুহার প্রতিটি ঘর একটি হ্যাশের সাথে মিলে যায়। হ্যাশ শুধুমাত্র একটি এন্ট্রি আছে. এলোমেলোভাবে বেছে নেওয়া ["n", "s", "e", "w"]-এর একটির মান "আপনি রুবি খুঁজে পেয়েছেন।" আপনি ভুলভাবে নির্বাচন করলে একটি নতুন হ্যাশ তৈরি করা হয় এবং গাছে যোগ করা হয়।

generator = Proc.new do |hash, key| 
  hash[key] = Hash.new(&generator).merge(["n", "s", "e", "w"][rand(4)] => "You found the ruby!")
end
dungeon = Hash.new(&generator)
dungeon["n"] # <Hash ...
dungeon["n"]["s"] # <Hash ...
dungeon["n"]["s"]["w"] # "You found the ruby!"


  1. রুবিতে বিটওয়াইজ হ্যাক

  2. রুবিতে ল্যাম্বডাস ব্যবহার করা

  3. রুবি 2.6-এ 9টি নতুন বৈশিষ্ট্য

  4. হ্যাশ টেবিল ব্যাখ্যা