রুবির লুকানো বৈশিষ্ট্য


160

মেমের "লুকানো বৈশিষ্ট্যগুলি ..." চালিয়ে যাওয়া, আসুন আমরা রুবি প্রোগ্রামিং ভাষার স্বল্প-জ্ঞাত তবে দরকারী বৈশিষ্ট্যগুলি ভাগ করি।

রেল স্টাফের কোনও রুবিকে ছাড়াই কোর রুবির সাথে এই আলোচনা সীমাবদ্ধ করার চেষ্টা করুন।

আরো দেখুন:

(দয়া করে, প্রতি উত্তরে কেবল একটি লুকানো বৈশিষ্ট্য))

ধন্যবাদ


সম্প্রদায় উইকি হওয়া উচিত
সাইলেন্টগোস্ট

উত্তর:


80

রুবি ১.৯ থেকে প্রোক # === প্রোক # কল করার জন্য একটি উপনাম, যার অর্থ প্রক্ট অবজেক্টসগুলি এরকম ক্ষেত্রে বিবৃতিতে ব্যবহার করা যেতে পারে:

def multiple_of(factor)
  Proc.new{|product| product.modulo(factor).zero?}
end

case number
  when multiple_of(3)
    puts "Multiple of 3"
  when multiple_of(7)
    puts "Multiple of 7"
end

1
এটি করার জন্য আমি আসলে এক পর্যায়ে একটি রত্ন লিখেছিলাম, তবে আমার কোডটি ছিল (ক) একটি জগাখিচুড়ি, এবং (খ) ধীর গতিতে। কার্যকারিতা এটিকে মূল হিসাবে তৈরি করেছে আমি খুব আনন্দিত।
জেমস এ রোজেন

76

পিটার কুপারের রুবি ট্রিকসের একটি ভাল তালিকা রয়েছে। সম্ভবত তার আমার প্রিয়টি একক আইটেম এবং সংগ্রহ উভয়ই গণনা করার অনুমতি দিচ্ছে। (এটি হ'ল একটি সংগ্রহশহী অবজেক্টটিকে কেবল সেই অবজেক্টের সমাহার হিসাবে বিবেচনা করুন)) এটি দেখতে এটির মতো দেখাচ্ছে:

[*items].each do |item|
  # ...
end

38
এই একটি অনেক বেশী সুনিদৃষ্ট (এবং এইভাবে সুন্দর) ফর্ম এরে (আইটেম) .each হয়
mislav

যদি itemsস্ট্রিং হয় তবে আপনাকে এটিকে [*…] এর সাথে সংযুক্ত করতে হবে না। স্ট্রিং.এচ কিছু অক্ষর অনুসারে অক্ষরগুলি পুনরাবৃত্তি করে না। এটি কেবল ব্লকে ফিরে আসে।
এমএক্সসিএল

এই কখনও ব্যবহার করবে? উৎসুক.
এড এস

1
@ এড: আপনি যদি কোনও পদ্ধতি লিখছেন এবং পদ্ধতিটির ব্যবহারকারীকে একটি ভেরাগস তালিকা বা একটি অ্যারে পাস করার অনুমতি দিতে চান তবে এটি দুর্দান্ত।
জেমস এ রোজেন 4

64

এটি কীভাবে গোপন রয়েছে তা জানেন না, তবে এক-মাত্রিক অ্যারে থেকে হ্যাশ তৈরি করার প্রয়োজনের সময় আমি এটি দরকারী পেয়েছি:

fruit = ["apple","red","banana","yellow"]
=> ["apple", "red", "banana", "yellow"]

Hash[*fruit]    
=> {"apple"=>"red", "banana"=>"yellow"}

নোট যা Hash[ [["apple","red"], ["banana","yellow"] ]একই ফলাফল উত্পাদন করে।
মার্ক-আন্দ্রে লাফোর্টুন

54

আমার পছন্দ করা একটি কৌশল *অ্যারে ব্যতীত অন্য বস্তুগুলিতে স্প্ল্যাট ( ) এক্সপেন্ডার ব্যবহার করা । নিয়মিত প্রকাশের ম্যাচের একটি উদাহরণ এখানে:

match, text, number = *"Something 981".match(/([A-z]*) ([0-9]*)/)

অন্যান্য উদাহরণের মধ্যে রয়েছে:

a, b, c = *('A'..'Z')

Job = Struct.new(:name, :occupation)
tom = Job.new("Tom", "Developer")
name, occupation = *tom

13
ঘটনাচক্রে, কৌতূহলের জন্য, এটি স্প্লিটের টার্গেটে স্পষ্টভাবে to_a কল করে কাজ করে।
বব আমান

1
আপনি যদি ম্যাচটিতে আগ্রহী না হন তবে আপনি তা করতে পারেন text, number = *"text 555".match(/regexp/)[1..-1]
অ্যান্ড্রু গ্রিম

text, number = "Something 981".scan(/([A-z]*) ([0-9]*)/).flatten.map{|m| Integer(m) rescue m}
জোনাস এলফস্ট্রাম

7
উভয় ভাল কৌশল, তবে এমন একটি বিষয় হতে পারে যেখানে এটি খুব বেশি যাদু, তাই না ?!
টম্যাফ্রো

1
@ অ্যান্ড্রু, আপনি কি বিবেচনা করেছেন, এই ম্যাচটি শূন্য করতে পারে? শিল নেই পদ্ধতি []
অ্যালেক্সি

52

বাহ, কেউই ফ্লিপ ফ্লপ অপারেটরের উল্লেখ করেনি:

1.upto(100) do |i|
  puts i if (i == 3)..(i == 15)
end

11
ঠিক আছে ... কারও আমাকে এটি বোঝাতে হবে explain এটি কাজ করে, তবে কেন আমি তা বুঝতে পারি না।
বব আমান

12
ফ্লিপ ফ্লপ অপারেটর যদি স্টেটফুল হয়। এর রাজ্যটি শীঘ্রই সত্যে i == 3স্যুইচ হয়ে যায় i != 3 এবং এর পরে এবং মিথ্যাতে স্যুইচ করে i == 15। ফ্লিপ-ফ্লপের মতো: এন.উইকিপিডিয়া.রোগ
কনস্টান্টিন হাজে

1
আমি একে একে গোপন বৈশিষ্ট্য বলব না, এতটা বিরক্তি। আমার মনে আছে বছর কয়েক আগে ফ্রিডিনে # রবিতে আমার সাথে এটির প্রথম পরিচয় হয়েছিল; আমি এটির ব্যতীত মূলত রুবির প্রতিটি বৈশিষ্ট্যই ব্যবহার করেছি ।
এলিওটিটিসিবল

1
আমি এটিকে বিরক্তি বলব না, এটি এমন কিছু যা আপনি ব্যবহার করেন নি। আমি এটি ব্যবহার করি এবং এটি কোডটি খুব সুন্দরভাবে হ্রাস করতে পারে, বিশেষত যখন আমি কিছু মানদণ্ডের ভিত্তিতে ফাইলগুলি থেকে লাইনগুলি ব্লক করে নিই।
টিন ম্যান

49

রুবি সম্পর্কে একটি দুর্দান্ত জিনিস হ'ল আপনি পদ্ধতিগুলিতে কল করতে পারেন এবং অন্য ভাষাগুলি যে জায়গাগুলির উপর ভিত্তি করে এমন পদ্ধতিতে কোড চালাতে পারেন যেমন পদ্ধতি বা শ্রেণির সংজ্ঞা হিসাবে।

উদাহরণস্বরূপ, একটি ক্লাস তৈরি করতে যার অজানা সুপারক্লাস রয়েছে রান সময় পর্যন্ত, অর্থাৎ এলোমেলো, আপনি নিম্নলিখিতটি করতে পারেন:

class RandomSubclass < [Array, Hash, String, Fixnum, Float, TrueClass].sample

end

RandomSubclass.superclass # could output one of 6 different classes.

এটি 1.9 Array#sampleপদ্ধতিটি ব্যবহার করে (কেবলমাত্র 1.8.7-এ, দেখুন)Array#choice ), এবং উদাহরণটি বেশ স্বীকৃত তবে আপনি এখানে শক্তি দেখতে পারেন।

অন্য একটি দুর্দান্ত উদাহরণ হ'ল ডিফল্ট প্যারামিটার মানগুলি রাখার ক্ষমতা যা স্থির নয় (অন্যান্য ভাষাগুলির মতো প্রায়শই দাবি করে):

def do_something_at(something, at = Time.now)
   # ...
end

অবশ্যই প্রথম উদাহরণটির সাথে সমস্যাটি হ'ল এটি কল সময় নয়, সংজ্ঞা সময়ে মূল্যায়ন করা হয়। সুতরাং, একবার একটি সুপারক্লাস নির্বাচন করা হয়ে গেলে, এটি সেই প্রোগ্রামের বাকী অংশের জন্য সেই সুপারক্লাস থেকে যায়।

তবে দ্বিতীয় উদাহরণে, আপনি যখনই কল করবেন do_something_atতখন atচলকটি পদ্ধতিটি বলা হওয়ার সময় হবে (ভাল, এর খুব কাছেই)


2
দ্রষ্টব্য: অ্যারে # র্যান্ড অ্যাক্টিভসপোর্ট দ্বারা সরবরাহ করা হয়েছে যা আপনি কারাগারের বাইরে খুব সহজেই ব্যবহার করতে পারবেনrequire 'activesupport'
rfunduk

অ্যারে # পছন্দটি 1.8.7 এ রয়েছে
জোশ লি

24
এরে # পছন্দ 1.8.7 হয় শুধুমাত্র ! এটি ব্যবহার করবেন না, এটি 1.9 এ চলে গেছে এবং 1.8.8 এ চলে যাবে। # নমুনাটি ব্যবহার করুন
মার্ক-অ্যান্ড্রে

অজগর: ক্লাস ডিক্টলিস্ট ([ডিক্ট, তালিকা] [এলোমেলো.আরেন্ডিন্ট (0,1)]): পাস
অনুরাগ ইউনিয়াল

Def do_something_at (কিছু, at = ল্যাম্বদা {সময়.নু}) at.call # এখন গতিশীলভাবে সময় শেষ করুন
জ্যাক কিনসেলা

47

আরেকটি ছোট বৈশিষ্ট্য - Fixnum36 এ কোনও বেসে রূপান্তর করুন :

>> 1234567890.to_s(2)
=> "1001001100101100000001011010010"

>> 1234567890.to_s(8)
=> "11145401322"

>> 1234567890.to_s(16)
=> "499602d2"

>> 1234567890.to_s(24)
=> "6b1230i"

>> 1234567890.to_s(36)
=> "kf12oi"

এবং হিউ ওয়াল্টাররা যেমন মন্তব্য করেছেন, অন্যভাবে রূপান্তর করা ঠিক তত সহজ:

>> "kf12oi".to_i(36)
=> 1234567890

1
এবং সম্পূর্ণতার জন্য, String#to_s(base)কোনও পূর্ণসংখ্যায় ফিরে রূপান্তর করতে ব্যবহার করা যেতে পারে; "1001001100101100000001011010010".to_i(2), "499602d2".to_i(16)ইত্যাদি সমস্ত আসলটি ফেরত দেয় Fixnum
হিউ ওয়াল্টার্স

40

ডিফল্ট মান সহ হ্যাশ! এই ক্ষেত্রে একটি অ্যারে।

parties = Hash.new {|hash, key| hash[key] = [] }
parties["Summer party"]
# => []

parties["Summer party"] << "Joe"
parties["Other party"] << "Jane"

রূপকবিদ্যায় খুব দরকারী।


1
হ্যাঁ সত্য। রুবি হ্যাশ '<<' অপারেটরকে গ্রহণ করতে পারে যদি ইতিমধ্যে '=' দিয়ে ডিফল্ট মান নির্ধারিত হয় (এটি খালি অ্যাসাইনমেন্টের পরেও পাত্তা দেবে না) অন্যথায় হ্যাশ '<<' স্বীকার করবে না। CMIIW
মোহাম্মদ

39

রুবি 1.9 উত্স ডাউনলোড করুন এবং ইস্যু করুন make golf , তারপরে আপনি এই জাতীয় জিনিসগুলি করতে পারেন:

make golf

./goruby -e 'h'
# => Hello, world!

./goruby -e 'p St'
# => StandardError

./goruby -e 'p 1.tf'
# => 1.0

./goruby19 -e 'p Fil.exp(".")'
"/home/manveru/pkgbuilds/ruby-svn/src/trunk"

golf_prelude.cআরও পরিষ্কার ঝরঝরে লুকিয়ে থাকার জন্য পড়ুন ।


38

1.9 প্রো কার্য কার্যকারিতাটিতে আরও একটি মজাদার সংযোজন হ'ল প্রোক # কারি যা আপনাকে প্রোক গ্রহণকারী এন আর্গুমেন্টগুলিকে একটি গ্রহণযোগ্য এন -1 রূপান্তর করতে দেয়। এখানে এটি উপরে উল্লিখিত প্রোক # === টিপের সাথে একত্রিত হয়েছে:

it_is_day_of_week = lambda{ |day_of_week, date| date.wday == day_of_week }
it_is_saturday = it_is_day_of_week.curry[6]
it_is_sunday = it_is_day_of_week.curry[0]

case Time.now
when it_is_saturday
  puts "Saturday!"
when it_is_sunday
  puts "Sunday!"
else
  puts "Not the weekend"
end

35

বুলিয়ান অপারেটরগুলি নন বুলিয়ান মানগুলিতে।

&& এবং ||

উভয়ই মূল্যায়িত সর্বশেষ অভিব্যক্তিটির মান ফেরত দেয়।

যে কারণে ||= ভেরিয়েবলটি অপরিজ্ঞাত করা হলে ডান দিকে মান প্রত্যাবর্তনের সাথে ভেরিয়েবলটি আপডেট করবে। এটি স্পষ্টভাবে নথিভুক্ত নয়, তবে সাধারণ জ্ঞান।

তবে এটি &&=সম্পর্কে এতটা ব্যাপকভাবে পরিচিত নয়।

string &&= string + "suffix"

সমতুল্য

if string
  string = string + "suffix"
end

এটি ধ্বংসাত্মক ক্রিয়াকলাপগুলির জন্য খুব কার্যকর যা ভেরিয়েবলটি অপরিজ্ঞাত করে থাকলে এগিয়ে যাওয়া উচিত নয়।


2
আরও স্পষ্টভাবে, string &&= string + "suffix" সমতুল্য string = string && string + "suffix"। এটি &&এবং ||তাদের দ্বিতীয় যুক্তিটি পিকএক্সে আলোচনা করা হয়েছে, পি। 154 (প্রথম ভাগ - রুবি এর চেহারা, অভিব্যক্তি, শর্তসাপেক্ষ কার্যকর)।
রিচার্ড মাইকেল 23

29

রেলগুলি সরবরাহ করে এমন প্রতীক # টু_প্রোক ফাংশনটি দুর্দান্ত।

পরিবর্তে

Employee.collect { |emp| emp.name }

তুমি লিখতে পারো:

Employee.collect(&:name)

এটি সম্ভবত আপত্তিজনকভাবে একটি ব্লক ব্যবহারের চেয়ে "ধীরে ধীরে ধীরে ধীরে বাড়ানোর ক্রম"। igvita.com/2008/07/08/6-optimization-tips-for-ruby-mri
চার্লস রোপার

আমি কেবল এটি চেষ্টা করে দেখেছি এবং দুজনের মধ্যে কোনও উল্লেখযোগ্য পার্থক্য নেই। আমি নিশ্চিত নই যে এই "আকারের ক্রম" জিনিসটি কোথা থেকে এসেছে। (রুবি 1.8.7 ব্যবহার করে)
ম্যাট গ্র্যান্ডে

1
কারাগারের বাইরে এটি করাও সহজ এবং require 'activesupport'যেহেতু এই সহায়তাকারীদের বেশিরভাগই আসল কারণ এটি করা সম্ভব be
rfunduk

8
এটি অ্যাক্টিভ_সপোর্টের প্রয়োগের কারণে ধীর হয়ে থাকত, যেমন এটি একাধিক যুক্তি গ্রহণ করে যাতে আপনি শীতল বিষ্ঠা (১..১০) করতে পারেন in সংগ্রহ যেমন% w (দ্রুত বাদামী শিয়াল)। মানচিত্র এবং: উপগ্রহ। 1.8.7 হিসাবে এটি মূল রুবি এবং কর্মক্ষমতা যুক্তিসঙ্গত।
স্টিভ গ্রাহাম

4
@ থেন্ডুকস: এবং এটি রুবি ১.৮..7 এবং ১.৯ এ অ্যাক্টিভসপোর্টের সাহায্য ছাড়াই করা যেতে পারে।
অ্যান্ড্রু গ্রিম

28

একটি চূড়ান্ত এক - রুবিতে আপনি স্ট্রিংগুলি সীমিত করতে চান এমন কোনও অক্ষর ব্যবহার করতে পারেন। নিম্নলিখিত কোড নিন:

message = "My message"
contrived_example = "<div id=\"contrived\">#{message}</div>"

আপনি যদি স্ট্রিংয়ের মধ্যে ডাবল-কোটগুলি থেকে বাঁচতে না চান তবে আপনি কেবল একটি ভিন্ন ডিলিমিটার ব্যবহার করতে পারেন:

contrived_example = %{<div id="contrived-example">#{message}</div>}
contrived_example = %[<div id="contrived-example">#{message}</div>]

ডিলিমিটারগুলি এড়াতে এড়ানো পাশাপাশি আপনি এই ডিলিটরগুলি আরও ভাল মাল্টলাইন স্ট্রিংয়ের জন্য ব্যবহার করতে পারেন:

sql = %{
    SELECT strings 
    FROM complicated_table
    WHERE complicated_condition = '1'
}

19
না কোনো অক্ষর, কিন্তু এটি এখনও বেশ শান্ত। এটি অন্যান্য আক্ষরিকের সাথেও কাজ করে:% () /% {} /% [] /% <> /% || % r () /% r {} /% r [] /% r <> /% r || % w () /% w {{/% w [] /% w <> /% ডাব্লু ||
বো জিনেস

এখানে হেরানো ডক সিনট্যাক্সও রয়েছে: << ব্লক ... ব্লক, যা আমি মাল্টলাইন এসকিউএল স্টেটমেন্ট ইত্যাদির মতো জিনিসগুলির জন্য ব্যবহার করতে চাই
মার্টিন টি।

26

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

((0..9).each do |n|
    define_method "press_#{n}" do
      @number = @number.to_i * 10 + n
    end
  end

উপরের কোডটি "প্রেস 9" এর মাধ্যমে "প্রেস 1" পদ্ধতিগুলি গতিশীলভাবে তৈরি করতে 'সংজ্ঞায়িত-সংক্রান্ত' কমান্ড ব্যবহার করে। তারপরে সমস্ত 10 টি পদ্ধতি টাইপ করুন যা সংক্ষিপ্তভাবে একই কোড ধারণ করে, সংজ্ঞায়িত পদ্ধতি কমান্ডটি ফ্লাইতে প্রয়োজনীয় পদ্ধতিগুলি তৈরি করতে ব্যবহৃত হয়।


4
সংজ্ঞায়িত_মেথডো এর সাথে একমাত্র সমস্যা হ'ল এটি রুবি ১.৮ এর পরামিতি হিসাবে ব্লকগুলি পাস করার অনুমতি দেয় না। কাজের জন্য এই ব্লগ পোস্ট দেখুন ।
অ্যান্ড্রু গ্রিম

26

অসীম অলস তালিকা হিসাবে একটি ব্যাপ্তি অবজেক্টটি ব্যবহার করুন:

Inf = 1.0 / 0

(1..Inf).take(5) #=> [1, 2, 3, 4, 5]

এখানে আরও তথ্য: http://banisterfiend.wordpress.com/2009/10/02/wtf-infinite-ranges-in-ruby/


লিঙ্কযুক্ত নিবন্ধে অলস_সलेक्टটি খুব ঝরঝরে।
জোসেফ ওয়েইসমান

এটি সত্যিই দুর্দান্ত। আমি পছন্দ করি ইনফিনিটি কীভাবে ভাসা, আমি যখন এই চেষ্টা করেছি: (-আইএনএফ..আইএনএফ) .টেক (4) এটি উত্থাপন করেছে (যুক্তিযুক্তভাবে সামঞ্জস্যপূর্ণ) ভাসমান ত্রুটি থেকে পুনরাবৃত্তি করতে পারে না। : ডি
জাচায়সান

23

module_function

মডিউল পদ্ধতিগুলি যে মডিউল_ফাংশন হিসাবে ঘোষিত হয়েছে সেগুলি ক্লাসে ব্যক্তিগত উদাহরণ পদ্ধতি হিসাবে নিজের অনুলিপি তৈরি করবে যার মধ্যে মডিউল রয়েছে:

module M
  def not!
    'not!'
  end
  module_function :not!
end

class C
  include M

  def fun
    not!
  end
end

M.not!     # => 'not!
C.new.fun  # => 'not!'
C.new.not! # => NoMethodError: private method `not!' called for #<C:0x1261a00>

আপনি যদি কোনও যুক্তি ছাড়াই মডিউল_ফানশন ব্যবহার করেন তবে মডিউল_ফাংশন স্টেটমেন্টের পরে আসা যে কোনও মডিউল পদ্ধতি স্বয়ংক্রিয়ভাবে নিজেই মডিউল_ফিউশন হয়ে যাবে।

module M
  module_function

  def not!
    'not!'
  end

  def yea!
    'yea!'
  end
end


class C
  include M

  def fun
    not! + ' ' + yea!
  end
end
M.not!     # => 'not!'
M.yea!     # => 'yea!'
C.new.fun  # => 'not! yea!'

4
আপনি যদি মডিউলগুলিতে ব্যক্তিগত পদ্ধতিগুলি ঘোষণা করতে চান তবে কেবল ব্যক্তিগত কীওয়ার্ডটি ব্যবহার করুন। মডিউলটি অন্তর্ভুক্ত ক্লাসগুলিতে পদ্ধতিটি বেসরকারী করার পাশাপাশি মডিউল দ্য ফাংশনটি মডিউল দৃষ্টান্তে পদ্ধতিটি অনুলিপি করে। বেশিরভাগ ক্ষেত্রে এটি আপনি চান তা নয়।
tomafro

আমি জানি আপনি কেবল ব্যক্তিগত ব্যবহার করতে পারেন। তবে এটি রুবির গোপন বৈশিষ্ট্যগুলির একটি প্রশ্ন। এবং, আমি মনে করি বেশিরভাগ মানুষ মডিউল_ফংশন (আমার অন্তর্ভুক্ত) সম্পর্কে কখনই শোনেনি যতক্ষণ না তারা ডকটিতে এটি দেখে এবং এটি দিয়ে খেলা শুরু করে।
নিউটোনপল

module_function(দ্বিতীয় উপায়) ব্যবহারের বিকল্প হ'ল ব্যবহার করা extend self(যা দেখতে বেশ সুন্দর দেখাচ্ছে: ডি)
J -_- L

23

সংক্ষিপ্ত ইনজেকশন, যেমন:

পরিসরের যোগফল:

(1..10).inject(:+)
=> 55

2
কাজ করার জন্য আপনার রুবি ১.৯ বা রুবি ১.৮ এর সাথে রেলগুলি দরকার।
এমএক্সসিএল

1
@ ম্যাক্স হাওল: বা require 'backports':-)
মার্ক-আন্দ্রে লাফোর্টুন

1
এটি কি হাইহয়ের উত্তরের সদৃশ নয়?
অ্যান্ড্রু গ্রিম

21

সতর্কতা: এই আইটেমটি ২০০৮ সালের # 1 হররেন্ডাস হ্যাককে ভোট দেওয়া হয়েছিল , তাই যত্ন সহ ব্যবহার করুন। আসলে, এটি প্লেগের মতো এড়িয়ে চলুন তবে এটি অবশ্যই লুকানো রুবি।

সুপারভাইররা রুবিতে নতুন অপারেটর যুক্ত করুন

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

সুপারভাইজার প্রকল্পটির প্রশংসা করার বাইরে আমার কিছু করার নেই ।


19

আমি পার্টিতে দেরি করেছি, কিন্তু:

আপনি সহজেই দুটি সম-দৈর্ঘ্যের অ্যারে নিতে পারেন এবং একটি অ্যারে কীগুলি সরবরাহ করে এবং অন্যটি মান সরবরাহ করে তাদের একটি হ্যাশে পরিণত করতে পারেন:

a = [:x, :y, :z]
b = [123, 456, 789]

Hash[a.zip(b)]
# => { :x => 123, :y => 456, :z => 789 }

(এটি কাজ করে কারণ অ্যারে # জিপ দুটি জিপ থেকে মানগুলি আপ করে:

a.zip(b)  # => [[:x, 123], [:y, 456], [:z, 789]]

এবং হ্যাশ [] ঠিক যেমন একটি অ্যারে নিতে পারে। আমি লোকেদের এটি করতেও দেখেছি:

Hash[*a.zip(b).flatten]  # unnecessary!

কোনটি একই ফলাফল দেয় তবে স্প্ল্যাট এবং চ্যাপ্টা পুরোপুরি অপ্রয়োজনীয় - সম্ভবত তারা অতীতে ছিল না?)


3
এটি প্রকৃতপক্ষে দীর্ঘ সময়ের জন্য বিনা প্রতিবেদনে ছিল (দেখুন redmine.ruby-lang.org/issues/show/1385 )। নোট করুন যে এই নতুন রূপটি রুবি ১.৮..7 এর কাছে নতুন
মার্ক-অ্যান্ড্রে

19

রুবিতে অটো-ভিভিফাইং হ্যাশ

def cnh # silly name "create nested hash"
  Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}
end
my_hash = cnh
my_hash[1][2][3] = 4
my_hash # => { 1 => { 2 => { 3 =>4 } } }

এটি কেবল জঘন্য কাজ হতে পারে।


1
দেশীয় হ্যাশ module InfHash; def self.new; Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}; end; end
থ্রি-

16

একটি অ্যারে তৈরি করা হচ্ছে

(a, b), c, d = [ [:a, :b ], :c, [:d1, :d2] ]

কোথায়:

a #=> :a
b #=> :b
c #=> :c
d #=> [:d1, :d2]

এই কৌশলটি ব্যবহার করে আমরা কোনও গভীরতার নেস্টেড অ্যারে থেকে সঠিক মানগুলি পেতে চাইলে সাধারণ অ্যাসাইনমেন্টটি ব্যবহার করতে পারি।


15

Class.new()

রান সময়ে নতুন ক্লাস তৈরি করুন। যুক্তিটি উত্পন্ন করার জন্য একটি শ্রেণি হতে পারে এবং ব্লকটি শ্রেণীর বডি। আপনি const_set/const_get/const_defined?নিজের নতুন ক্লাসটি সঠিকভাবে নিবন্ধভুক্ত করার জন্যও নজর রাখতে পারেন, যাতে inspectকোনও সংখ্যার পরিবর্তে একটি নাম ছাপে।

আপনার প্রতিদিন প্রয়োজন এমন কিছু নয়, আপনি যখন করেন তখন বেশ কার্যকর।


1
MyClass = Class.new Array do; def hi; 'hi'; end; endসমতূল্য মনে করা হয় class MyClass < Array; def hi; 'hi'; end; end
yfeldblum

1
আমি যতটা ভেবেছি তার চেয়ে বেশি সম্ভবত সত্য। এমনকি এটি প্রদর্শিত হয় যে আপনি কেবল একটি ধ্রুবকের পরিবর্তে পরিবর্তনশীল থেকে উত্তরাধিকারী হতে পারেন। যাইহোক, সুগার্ড সংস্করণ (দ্বিতীয়) কাজ করার সময় উপস্থিত হয় না যদি আপনার রান সময় ক্লাসের নামটি নির্মাণ করা প্রয়োজন। (বেয়ারিং ইভাল অবশ্যই।)
জাস্টিন

এই কৌশলটি মেটাপগ্রোমিং রুবি বইয়ে বেশ সুন্দরভাবে বর্ণনা করা হয়েছে ।
পল প্লেডিজ

13

একটানা সংখ্যার একটি অ্যারে তৈরি করুন:

x = [*0..5]

এক্স সেট করে [0, 1, 2, 3, 4, 5]


হ্যাঁ, তবে এটি সংক্ষিপ্ত এবং মিষ্টি হিসাবে খুব সহজ নয়;)
ঘোড়াওয়ালা

2
অদ্বিতীয়ত উদ্দেশ্য, পাঠযোগ্যতা স্বাদ এবং অভিজ্ঞতার বিষয়
অ্যালেক্সি

স্প্ল্যাট ( *) অপারেটর মূলত যেভাবে কল করে to_a
ম্যাথিউস মোরইরা

13

রুবিল্যান্ডে আপনি যে যাদু দেখছেন তার অনেকগুলি রূপক প্রয়োগের সাথে সম্পর্কিত যা কেবল আপনার জন্য কোড লিখতে কোড লিখতে পারে। রুবি এর attr_accessor, attr_readerএবং attr_writer, সমস্ত সহজ metaprogramming হয় যে, তারা এক লাইন দুটি পদ্ধতি, একটি প্রমিত প্যাটার্ন নিম্নলিখিত তৈরি করুন। ব্যান্ডগুলি তাদের সম্পর্ক-পরিচালনার পদ্ধতিগুলির মতো has_oneএবং এর সাথে পুরোপুরি রূপক তৈরি করেbelongs_to

তবে class_evalগতিশীল-লিখিত কোডটি কার্যকর করতে আপনার নিজস্ব রূপক কৌশলগুলি তৈরি করা বেশ সহজ ।

নিম্নলিখিত উদাহরণটি একটি মোড়ক বস্তুকে অভ্যন্তরীণ অবজেক্টের সাথে নির্দিষ্ট পদ্ধতিগুলি ফরোয়ার্ড করার অনুমতি দেয়:

class Wrapper
  attr_accessor :internal

  def self.forwards(*methods)
    methods.each do |method|
      define_method method do |*arguments, &block|
        internal.send method, *arguments, &block
      end
    end
  end

  forwards :to_i, :length, :split
end

w = Wrapper.new
w.internal = "12 13 14"
w.to_i        # => 12
w.length      # => 8
w.split('1')  # => ["", "2 ", "3 ", "4"]

পদ্ধতিটি Wrapper.forwardsপদ্ধতির নামের জন্য প্রতীক নেয় এবং methodsএগুলিগুলিতে সংরক্ষণ করে। তারপরে, প্রদত্ত প্রত্যেকটির জন্য, আমরা ব্যবহার করিdefine_method একটি নতুন পদ্ধতি তৈরি যার কাজটি সমস্ত যুক্তি এবং ব্লক সহ বার্তা প্রেরণ করা।

রূপান্তরিত ইস্যুগুলির একটি দুর্দান্ত সংস্থান হ'ল লাকি স্টিফের "পরিষ্কারভাবে দেখা মেটাট্রোগ্রামিং"


আমি রুবিতে রূপান্তরকরে প্রথমে মাথা ডুবতে চাই। আপনি এটি দিয়ে শুরু করার জন্য কিছু রেফারেন্স সরবরাহ করতে পারেন (প্রদত্ত লিঙ্কটি ব্যতীত)? বইগুলিও করবে। ধন্যবাদ।
চিরন্তন

প্রাগপ্রোগের ভিডিওোকাস্টিং সেরি "রুবি অবজেক্ট মডেল অ্যান্ড মেটাপ্রোগ্রামিং" এটি রুবি ব্যবহার করে মেটা প্রোগ্রামিংয়ের একটি ভাল পরিচয়: pragprog.com/screencasts/v-dtrubyom/…
ক্যাফো

@Chirantan, কটাক্ষপাত আছে Metaprogramming রুবি
পল প্লেডিজ

12

===(obj)কেস তুলনার জন্য সাড়া দেয় এমন কিছু ব্যবহার করুন :

case foo
when /baz/
  do_something_with_the_string_matching_baz
when 12..15
  do_something_with_the_integer_between_12_and_15
when lambda { |x| x % 5 == 0 }
  # only works in Ruby 1.9 or if you alias Proc#call as Proc#===
  do_something_with_the_integer_that_is_a_multiple_of_5
when Bar
  do_something_with_the_instance_of_Bar
when some_object
  do_something_with_the_thing_that_matches_some_object
end

Module(এবং এইভাবে Class), Regexp, Date, এবং অন্যান্য অনেক ক্লাস একটি দৃষ্টান্ত পদ্ধতি নির্ধারণ: === (অন্যান্য), এবং সমস্ত ব্যবহার করা যাবে।

রুবি ১.৯- এর মতো এলিয়াস হওয়ার স্মরণ করিয়ে দেওয়ার জন্য ফারেলকে ধন্যবাদ জানাইProc#callProc#===


11

"রুবি" বাইনারি (কমপক্ষে এমআরআই এর) পার্ল ওয়ান-লাইনারকে বেশ জনপ্রিয় করে তোলে এমন অনেকগুলি সুইচ সমর্থন করে।

তাৎপর্যপূর্ণ:

  • -n মাত্র "পায়" দিয়ে একটি বহিরাগত লুপ সেট আপ করুন - যা প্রদত্ত ফাইলের নাম বা এসটিডিনের সাথে যাদুতে কাজ করে, প্রতিটি পড়ার লাইন $ _ এ সেট করে
  • -p এর মতো -n তবে putপ্রতিটি লুপের পুনরাবৃত্তির শেষে একটি স্বয়ংক্রিয় গুলি
  • -এ প্রতিটি ইনপুট লাইনে .স্প্লিট করতে স্বয়ংক্রিয় কল $ F এ সঞ্চিত
  • -i ইন-প্লেস ইনপুট ফাইলগুলি সম্পাদনা করুন
  • ইনপুট নেভিগেশন .chomp এ স্বয়ংক্রিয় কল
  • - আমরা একটি টুকরা কোড কার্যকর করি
  • -c উত্স কোড পরীক্ষা করুন
  • - আমরা সতর্কতা সহ

কিছু উদাহরণ:

# Print each line with its number:
ruby -ne 'print($., ": ", $_)' < /etc/irbrc

# Print each line reversed:
ruby -lne 'puts $_.reverse' < /etc/irbrc

# Print the second column from an input CSV (dumb - no balanced quote support etc):
ruby -F, -ane 'puts $F[1]' < /etc/irbrc

# Print lines that contain "eat"
ruby -ne 'puts $_ if /eat/i' < /etc/irbrc

# Same as above:
ruby -pe 'next unless /eat/i' < /etc/irbrc

# Pass-through (like cat, but with possible line-end munging):
ruby -p -e '' < /etc/irbrc

# Uppercase all input:
ruby -p -e '$_.upcase!' < /etc/irbrc

# Same as above, but actually write to the input file, and make a backup first with extension .bak - Notice that inplace edit REQUIRES input files, not an input STDIN:
ruby -i.bak -p -e '$_.upcase!' /etc/irbrc

আরও বেশি ব্যবহারযোগ্য এবং ব্যবহারিক উদাহরণের জন্য গুগল "রুবি ওয়ান-লাইনার" এবং "পার্ল ওয়ান-লাইনার" নির্দ্বিধায় অনুভব করুন। এটি মূলত আপনাকে রুবিকে অ্যাড এবং সিডের মোটামুটি শক্তিশালী প্রতিস্থাপন হিসাবে ব্যবহার করতে দেয়।


10

পাঠান () পদ্ধতি সাধারণ পদ্ধতি যা রুবি যে কোন ক্লাস বা বস্তুর উপর ব্যবহার করা যেতে পারে। যদি ওভাররাইড না করা হয় তবে প্রেরণ () একটি স্ট্রিং গ্রহণ করে এবং সেই পদ্ধতির নাম কল করে যার স্ট্রিংটি এটি পাস হয়েছে। উদাহরণস্বরূপ, যদি ব্যবহারকারী "ক্লার" বোতামটি ক্লিক করেন, তবে 'প্রেস_স্লেয়ার' স্ট্রিং প্রেরণ () পদ্ধতিতে প্রেরণ করা হবে এবং 'প্রেস_সিয়ার' পদ্ধতিটি কল করা হবে। প্রেরণ () পদ্ধতিটি রুবিতে ফাংশনগুলি কল করার জন্য একটি মজাদার এবং গতিশীল উপায়ের অনুমতি দেয়।

 %w(7 8 9 / 4 5 6 * 1 2 3 - 0 Clr = +).each do |btn|
    button btn, :width => 46, :height => 46 do
      method = case btn
        when /[0-9]/: 'press_'+btn
        when 'Clr': 'press_clear'
        when '=': 'press_equals'
        when '+': 'press_add'
        when '-': 'press_sub'
        when '*': 'press_times'
        when '/': 'press_div'
      end

      number.send(method)
      number_field.replace strong(number)
    end
  end

আমি ব্লগিং জুতাগুলিতে এই বৈশিষ্ট্য সম্পর্কে আরও কথা বলি : সিম্পল-ক্যালক অ্যাপ্লিকেশন


সুরক্ষা গর্তটি খোলার দুর্দান্ত উপায়টির মতো শোনাচ্ছে।
এমপি।

4
আমি যেখানেই সম্ভব প্রতীক ব্যবহার করব।
reto

9

কিছু শ্রেণি বা মডিউলটিকে বোকা বানানোর জন্য এটির এমন কিছু প্রয়োজন রয়েছে যা এর সত্যই প্রয়োজন হয় না:

$" << "something"

এটি উদাহরণস্বরূপ দরকারী যখন A এর পরিবর্তে বি প্রয়োজন হয় তবে আমাদের কোডে আমাদের বিয়ের দরকার হয় না (এবং এ আমাদের কোডের মাধ্যমে এটি ব্যবহার করবে না):

উদাহরণস্বরূপ, ব্যাকগ্রাউন্ডআরবস bdrb_test_helper requires 'test/spec', তবে আপনি একেবারেই ব্যবহার করেন না, তাই আপনার কোডে:

$" << "test/spec"
require File.join(File.dirname(__FILE__) + "/../bdrb_test_helper")

জহর এ-এর ফু -১.০.০ প্রয়োজন, এবং রত্ন বি-এর জন্য ফু-১.০.১ প্রয়োজন কি এই সমস্যার সমাধান করে?
অ্যান্ড্রু গ্রিম

না কারণ "কিছু" এর কোড উপলব্ধ হবে না: এটি কেবল অনুকরণ করে যে "কিছু" প্রয়োজনীয়, তবে এটি সত্যই এটির প্রয়োজন হয় না। $ "হ'ল একটি অ্যারে যা মডিউলের নামগুলি আবশ্যক দ্বারা লোড করা হয় (এটি প্রয়োজনীয়ভাবে দুটি বার মডিউল লোড করা রোধ করতে ব্যবহৃত হয়) তাই আপনি যদি রত্নকে বোকা বানানোর জন্য এটি ব্যবহার করেন তবে রত্নগুলি প্রকৃত" কিছু "ব্যবহার করার চেষ্টা করলে ক্রাশ হবে কোড, কারণ এটি বিদ্যমান নেই You আপনি পরিবর্তে কোনও মণির একটি কংক্রিট সংস্করণ (উদাহরণস্বরূপ foo-1.0.0) জোর করে চাপিয়ে দিতে চাইতে পারেন: ডকস.আরবিজেমস.আর.আউটড
olegueret

9

Fixnum#to_s(base)সত্যিই কিছু ক্ষেত্রে কার্যকর হতে পারে। এ জাতীয় একটি ক্ষেত্রে র্যান্ডম সংখ্যাকে স্ট্রিংয়ে 36 এর বেস ব্যবহার করে র্যান্ডম (সিউডো) অনন্য টোকেন তৈরি করা হচ্ছে।

8 দৈর্ঘ্যের টোকেন:

rand(36**8).to_s(36) => "fmhpjfao"
rand(36**8).to_s(36) => "gcer9ecu"
rand(36**8).to_s(36) => "krpm0h9r"

দৈর্ঘ্যের 6 টোকেন:

rand(36**6).to_s(36) => "bvhl8d"
rand(36**6).to_s(36) => "lb7tis"
rand(36**6).to_s(36) => "ibwgeh"

9

এমন একটি পন্থা সংজ্ঞা দেওয়া যা কোনও সংখ্যক প্যারামিটার গ্রহণ করে এবং সেগুলি সমস্ত ত্যাগ করে

def hello(*)
    super
    puts "hello!"
end

উপরের helloপদ্ধতিটি কেবল puts "hello"পর্দায় এবং কল করতে হবে super- তবে যেহেতু সুপারক্লাসটি helloপ্যারামিটারগুলিও সংজ্ঞায়িত করে - তবে এটি যেহেতু প্যারামিটিগুলি নিজেই ব্যবহার করার প্রয়োজন নেই - এটি তাদের কোনও নাম দেওয়ার দরকার নেই।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.