রুবি মেটাপগ্রোমিং: গতিশীল উদাহরণের পরিবর্তনশীল নাম


95

ধরা যাক আমার কাছে নিম্নলিখিত হ্যাশ রয়েছে:

{ :foo => 'bar', :baz => 'qux' }

কীভাবে আমি কীভাবে কী কী এবং মানগুলিকে কোনও বস্তুর উদাহরণ ভেরিয়েবল হতে সেট করতে পারি ...

class Example
  def initialize( hash )
    ... magic happens here...
  end
end

... যাতে আমি নীচের মডেল ভিতরে শেষ ...

@foo = 'bar'
@baz = 'qux'

?

উত্তর:


169

আপনি যে পদ্ধতিটি সন্ধান করছেন তা হ'ল instance_variable_set। সুতরাং:

hash.each { |name, value| instance_variable_set(name, value) }

বা আরও সংক্ষেপে,

hash.each &method(:instance_variable_set)

যদি আপনার উদাহরণের পরিবর্তনশীল নামগুলি "@" অনুপস্থিত থাকে (যেমন সেগুলি ওপির উদাহরণে রয়েছে), আপনাকে এগুলি যুক্ত করতে হবে, তাই এটি আরও পছন্দ হবে:

hash.each { |name, value| instance_variable_set("@#{name}", value) }

18
1.9.3 এর জন্য আমার পক্ষে কাজ করেনি। আমি এর পরিবর্তে এটি ব্যবহার করেছিhash.each {|k,v| instance_variable_set("@#{k}",v)}
আন্দ্রেই

4
রুবিকে ভালবাসার আর একটি কারণ
jschorr

আপনি দয়া করে ব্যাখ্যা করতে পারেন কীভাবে hash.each &method(:instance_variable_set), পদ্ধতিটি instance_variable_setযে দুটি পরামিতিগুলির প্রয়োজন তা গ্রহণ করে?
আর্নল্ড রোয়া

এই পুনরাবৃত্তি কিভাবে করতে কোন ধারণা? (যদি ইনপুট হ্যাশে একাধিক স্তর থাকে)
হ্যাশটিতে নিমেনেমস

13
h = { :foo => 'bar', :baz => 'qux' }

o = Struct.new(*h.keys).new(*h.values)

o.baz
 => "qux" 
o.foo
 => "bar" 

4
এটি বেশ আকর্ষণীয় ... দ্বিতীয় শৃঙ্খলিত .new()কাজটি ঠিক কী করছে?
অ্যান্ড্রু

4
@ অ্যান্ড্রু: Struct.newহ্যাশ কীগুলির উপর ভিত্তি করে একটি নতুন ক্লাস তৈরি করে এবং তারপরে দ্বিতীয়টি হ্যাশের মানগুলিতে প্রাথমিকভাবে সজ্জিত শ্রেণীর newপ্রথম অবজেক্ট তৈরি করে। রুবি
ডোক.আর.কম /

4
এটি আসলে এটি করার একটি দুর্দান্ত উপায় কারণ স্ট্রাক্ট যা তৈরি করেছেন এটি এটি অনেকটাই।
চক

4
অথবা ওপেনস্ট্রাক্ট ব্যবহার করুন । require 'ostruct'; h = {:foo => 'foo'}; o = OpenStruct.new(h); o.foo == 'foo'
জাস্টিন ফোর্স

আমাকে প্রতীকগুলিতে আমার কীগুলি ম্যাপ করতে হয়েছিল:Struct.new(*hash.keys.map { |str| str.to_sym }).new(*hash.values)
23

8

আপনি আমাদের কাঁদতে চান :)

যাই হোক না কেন, দেখুন Object#instance_variable_getএবংObject#instance_variable_set

শুভ কোডিং।


হ্যাঁ, আমি ভাবতে সাহায্য করতে পারি না ... কেন? কখন এটি ব্যবহার করার ভাল সময় হবে?
জাচ স্মিথ

উদাহরণস্বরূপ, আমি জেনেরিক থাকতে চাই set_entity সমস্ত কন্ট্রোলারদের জন্য কলব্যাক পেতে চাই এবং আমি বিদ্যমান উদাহরণের ভেরিয়েবলগুলির সাথে হস্তক্ষেপ করতে চাই নাdef set_entity(name, model); instance_variable_set(name, model.find_by(params[:id])); end;
user1201917

5

আপনি এটি ব্যবহার করতে পারেন sendযা ব্যবহারকারীকে অস্তিত্বের ইনস্ট্যান্স ভেরিয়েবলগুলি সেট করতে বাধা দেয়:

def initialize(hash)
  hash.each { |key, value| send("#{key}=", value) }
end

sendআপনার ক্লাসে যখন attr_accessorআপনার দৃষ্টান্তের ভেরিয়েবলগুলির মতো সেটার থাকে তখন ব্যবহার করুন :

class Example
  attr_accessor :foo, :baz
  def initialize(hash)
    hash.each { |key, value| send("#{key}=", value) }
  end
end
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.