সমান ?, একল ?, ===, এবং == এর মধ্যে পার্থক্য কী?


552

আমি এই চারটি পদ্ধতির মধ্যে পার্থক্যটি বোঝার চেষ্টা করছি। আমি ডিফল্টরূপে জানি যে ==পদ্ধতিটি কল করে equal?যখন সত্য উভয় অপারেন্ড একই বস্তুকে নির্দেশ করে তখন সত্য হয়।

===ডিফল্টরূপে এছাড়াও কল এলে ==যা কল equal?... ঠিক আছে, তাই যদি এই সব তিনটি পদ্ধতির ওভাররাইড করা হয় না, তারপর আমি অনুমান ===, ==এবং equal?ঠিক একই জিনিস করে?

এখন আসে eql?। এটি (ডিফল্টরূপে) কী করে? এটি অপারেন্ডের হ্যাশ / আইডি কল করে?

কেন রুবির এত সমতা চিহ্ন আছে? শব্দার্থবিজ্ঞানের মধ্যে কি তাদের পার্থক্য রয়েছে?


আমি শুধু একটি irb শুরু নিম্নলিখিত ফলাফল যা পুলিশের contradicts ছিল ... এই 3 সবই সত্য: "a" == "a", "a" === "a"এবং "a".eql? "a"। তবে এটি মিথ্যা: "a".equal? "a"(আমার রুবি 1.9.2-p180)
পিটারওয়ং

7
@ পিটার: কারণ স্ট্রিংগুলি সমস্ত সাম্যতা অপারেটরকে ওভাররাইড করে। ব্যবহার চেষ্টা a = Object.new; b = Object.newতাহলে সব ==, ===, .equal?, .eql?ফিরে আসবে trueজন্য aবনাম aএবং জন্য মিথ্যা aবনাম b
নিমো 157

উত্তর:


785

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

পার্শ্ব দ্রষ্টব্য: আপনি যদি নিজের কাছে বিভিন্ন জিনিসগুলিতে চেষ্টা করে দেখতে চান তবে এই জাতীয় কিছু ব্যবহার করুন:

class Object
  def all_equals(o)
    ops = [:==, :===, :eql?, :equal?]
    Hash[ops.map(&:to_s).zip(ops.map {|s| send(s, o) })]
  end
end

"a".all_equals "a" # => {"=="=>true, "==="=>true, "eql?"=>true, "equal?"=>false}

== - জেনেরিক "সমতা"

অবজেক্ট স্তরে, ==ফেরৎ সত্য শুধুমাত্র যদি objএবং otherএকই বস্তুর হয়। সাধারণত, শ্রেণি-নির্দিষ্ট অর্থ প্রদানের জন্য এই পদ্ধতিটি বংশধর শ্রেণিতে ওভাররাইড করা হয়।

এটি সর্বাধিক সাধারণ তুলনা, এবং এইভাবে সবচেয়ে মৌলিক জায়গা যেখানে আপনি (শ্রেণির লেখক হিসাবে) সিদ্ধান্ত নিতে পারেন যে দুটি বস্তু "সমান" কিনা।

=== - ক্ষেত্রে সমতা

ক্লাস অবজেক্টের জন্য, কার্যকরভাবে কলিংয়ের সমান #==, তবে সাধারণত বংশধরদের দ্বারা ক্ষেত্রে বিবৃতিতে অর্থবোধক শব্দার্থ সরবরাহ করতে পারে না।

এটি অবিশ্বাস্যভাবে দরকারী। আকর্ষণীয় ===বাস্তবায়ন রয়েছে এমন জিনিসগুলির উদাহরণ :

  • পরিসর
  • Regex
  • প্রক (রুবি ২.৯-এ)

সুতরাং আপনি যেমন কাজ করতে পারেন:

case some_object
when /a regex/
  # The regex matches
when 2..4
  # some_object is in the range 2..4
when lambda {|x| some_crazy_custom_predicate }
  # the lambda returned true
end

কীভাবে + কোডকে অনেক বেশি পরিষ্কার করতে পারে তার একটি ঝরঝরে উদাহরণের জন্য আমার উত্তরটি এখানে দেখুন । এবং অবশ্যই, আপনার নিজস্ব বাস্তবায়ন সরবরাহ করে, আপনি কাস্টম শব্দার্থবিজ্ঞান পেতে পারেন ।caseRegex===case

eql?- Hashসমতা

eql?পদ্ধতি ফেরৎ সত্য যদি objএবং otherএকই হ্যাশ কী পড়ুন। এটি Hashসদস্যদের সাম্যের জন্য পরীক্ষা করার জন্য ব্যবহৃত হয় । ক্লাসের অবজেক্টের জন্য Object, eql?সমার্থক ==সাবক্লাসগুলি সাধারণত eql?তাদের overতিহ্যবাহিত ==পদ্ধতিটি বাদ দিয়ে এই traditionতিহ্যকে অব্যাহত রাখে , তবে ব্যতিক্রমগুলি রয়েছে। Numericপ্রকারভেদ, উদাহরণস্বরূপ, জুড়ে টাইপ রূপান্তর সম্পাদন করে ==তবে পুরোদিকে নয় eql?, তাই:

1 == 1.0     #=> true
1.eql? 1.0   #=> false

সুতরাং আপনি নিজের ব্যবহারের জন্য এটিকে ওভাররাইড করতে পারেন বা আপনি দুটি ওপেনারাইড ==ও ব্যবহার করতে পারেন alias :eql? :==যাতে দুটি পদ্ধতি একইভাবে আচরণ করে।

equal? - পরিচয় তুলনা

বিপরীতে ==, equal?পদ্ধতিটি কখনই সাবক্লাস দ্বারা ওভাররাইড করা উচিত নয়: এটি অবজেক্টের পরিচয় নির্ধারণ করতে ব্যবহৃত হয় (এটি যদি a.equal?(b)আইএফএফ aহিসাবে একই বস্তু হয় b)।

এটি কার্যকরভাবে পয়েন্টার তুলনা।


32
আপনার উত্তর থেকে আমি যেমন বুঝতে পারি, কঠোরতা: সমান? <একল? <== <===। সাধারণত, আপনি == ব্যবহার করেন। কিছু শিথিল উদ্দেশ্যে, আপনি === ব্যবহার করুন। কড়া পরিস্থিতির জন্য, আপনি eql ?, এবং সম্পূর্ণ পরিচয়ের জন্য, আপনি সমান ব্যবহার করেন ?.
সাওয়া

21
কঠোরতার ধারণাটি ডকুমেন্টেশনে প্রয়োগ করা বা এমনকি প্রস্তাবিত হয় না, এটি ঠিক এর Numericচেয়ে কঠোরভাবে পরিচালনা করে ==। এটি সত্যিই শ্রেণীর লেখকের উপর নির্ভর করে। বিবৃতি ===বাইরে কখনও কখনও ব্যবহৃত হয় case
jtbandes

4
== বৃহত্তর / ছোট ক্ষেত্রেও সমতা। যেমন, আপনি যদি তুলনামূলক অন্তর্ভুক্ত করেন তবে এটি <=> ফিরে আসা ০ এর শর্তে সংজ্ঞায়িত হবে This এজন্য 1 == 1.0 রিটার্নটি সত্য।
এপিওরোস

5
@ সাওয়া আমি সাধারণত ==="ম্যাচ" (মোটামুটি) অর্থ হিসাবে মনে করি । যেমনটি রয়েছে, "রেজিপেক্স স্ট্রিংটির সাথে মেলে" বা "পরিসীমাটি মেলে (অন্তর্ভুক্ত) সংখ্যাটি করে"।
কেলভিন 21

7
মজাদার ঘটনা: সরকারী দস্তাবেজগুলি এখন এই উত্তরের সাথে লিঙ্ক করেছে (দেখুন রুবি- ডক.অর্গ.ও. / কোর্স ২.১.৫/২ )।
মার্ক আমেরিকা

46

আমি জেটব্যান্ডস উত্তরটি পছন্দ করি তবে এটি যেহেতু এটি দীর্ঘ দীর্ঘ, তাই আমি আমার নিজের কমপ্যাক্ট উত্তরটি যুক্ত করব:

==, ===, eql?,equal?
4 comparators, অর্থাত্ আছে। 2 টি বস্তুর তুলনায় 4 টি উপায়, রুবিতে।
যেমন, রুবিতে, সমস্ত তুলনাকারী (এবং বেশিরভাগ অপারেটর) আসলে পদ্ধতি-কল হয়, আপনি এই তুলনা পদ্ধতিগুলির শব্দার্থতাকে নিজেই পরিবর্তন করতে, ওভাররাইট করতে এবং সংজ্ঞা দিতে পারেন। তবে এটি বোঝা গুরুত্বপূর্ণ, যখন রুবির অভ্যন্তরীণ ভাষাটি কোন তুলনামূলক ব্যবহার করে:

==(মান তুলনা)
রুবি ব্যবহার করে: == সর্বত্র 2 টি অবজেক্টের মানের তুলনা করতে । হ্যাশ-মান:

{a: 'z'}  ==  {a: 'Z'}    # => false
{a: 1}    ==  {a: 1.0}    # => true

===(কেস তুলনা)
রুবি ব্যবহার করে: === ক্ষেত্রে / যখন তৈরি হয়। নিম্নলিখিত কোড স্নিপেটগুলি যুক্তিযুক্তভাবে অভিন্ন:

case foo
  when bar;  p 'do something'
end

if bar === foo
  p 'do something'
end

eql?(হ্যাশ-কী তুলনা)
রুবি ব্যবহার করে: একল? (পদ্ধতি হ্যাশের সাথে সংমিশ্রণে) হ্যাশ-কীগুলি তুলনা করতে। বেশিরভাগ ক্লাসে: একল? এর সাথে অভিন্ন: ==।
সম্পর্কে জ্ঞান: একল? কেবলমাত্র গুরুত্বপূর্ণ যখন আপনি নিজের বিশেষ ক্লাস তৈরি করতে চান:

class Equ
  attr_accessor :val
  alias_method  :initialize, :val=
  def hash()           self.val % 2             end
  def eql?(other)      self.hash == other.hash  end
end

h = {Equ.new(3) => 3,  Equ.new(8) => 8,  Equ.new(15) => 15}    #3 entries, but 2 are :eql?
h.size            # => 2
h[Equ.new(27)]    # => 15

দ্রষ্টব্য: সাধারণত ব্যবহৃত রুবি-শ্রেণীর সেট হ্যাশ-কী-তুলনার উপরও নির্ভর করে।

equal?(বস্তুর পরিচয় তুলনা)
রুবি ব্যবহার: সমান? দুটি বস্তু অভিন্ন কিনা তা পরীক্ষা করতে। এই পদ্ধতিটি (ক্লাসিক বেসিকজেক্টের) ওভাররাইট করার কথা নয়।

obj = obj2 = 'a'
obj.equal? obj2       # => true
obj.equal? obj.dup    # => false

30
এটি একটি ভাল উত্তর, তবে এটি প্রায় জেটিব্যান্ডসের হিসাবে দীর্ঘ। :)
অদ্ভুততা

2
@ অডিগিটি, প্রায় 70% দীর্ঘ। আমি 30% ব্যয় করতে অনেক কিছুই ভাবতে পারি।
কেরি সোভোল্যান্ড 21

আমি মনে করি এর উদাহরণটি eql?খুব বিভ্রান্তিকর। eql?একটি সাম্যতা তুলনা যা হ্যাশ গণনা করা হয় তার সাথে সামঞ্জস্যপূর্ণ , অর্থাত a.eql?(b)গ্যারান্টি দেয় a.hash == b.hash। এটি কেবল হ্যাশ কোডগুলি তুলনা করে না
আন্দ্রে তারানসভ 16

Is ক্ষেত্রে তুলনা সত্যিই সমতূল্য bar === fooএবং foo === bar? আমি আশা করব যে উত্তরটি সঠিক ছিল এবং এটি গুরুত্বপূর্ণ কারণ সংকলক বাম দিকে ডেকে: === `'
অ্যালেক্সিস উইলক

যতদূর আমি জানি, এটি হ'ল bar === foo: রুবি বাম হাতের কেস মানটি এবং ডানদিকে কেস ভেরিয়েবল ব্যবহার করে। এটি এনপিইগুলি (নাল পয়েন্টার ব্যতিক্রম) এড়িয়ে যাওয়ার সাথে থাকতে পারে।
আন্দ্রেয়াস রায়ও নিপ

33

সমতা অপারেটর: == এবং! =

== অপারেটর, যাকে সমতা বা দ্বিগুণ সমান হিসাবেও পরিচিত, যদি উভয় বস্তু সমান এবং মিথ্যা না হয় তবে সত্যটি ফিরে আসবে।

"koan" == "koan" # Output: => true

! = অপারেটর, বৈষম্য হিসাবেও পরিচিত, == এর বিপরীত। উভয় বস্তু সমান এবং মিথ্যা না হলে এটি সত্য হবে।

"koan" != "discursive thought" # Output: => true

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

বিভিন্ন ধরণের সংখ্যার তুলনা করার সময় (যেমন, পূর্ণসংখ্যা এবং ভাসমান), যদি তাদের সংখ্যার মান একই হয়, তবে == সত্যই ফিরে আসবে।

2 == 2.0 # Output: => true

সমান?

অপারেটরের বিপরীতে যা উভয় অপারেন্ড সমান হয় কিনা তা পরীক্ষা করে, দুটি অপারেন্ড একই বস্তুকে বোঝায় কিনা সমান পদ্ধতিটি পরীক্ষা করে। এটি রুবির সাম্যের শক্ততম রূপ।

উদাহরণ: a = "জেন" বি = "জেন"

a.object_id  # Output: => 20139460
b.object_id  # Output :=> 19972120

a.equal? b  # Output: => false

উপরের উদাহরণে, আমাদের একই মান সহ দুটি স্ট্রিং রয়েছে। যাইহোক, তারা দুটি স্বতন্ত্র অবজেক্ট, বিভিন্ন বস্তুর আইডি সহ। সুতরাং, সমান? পদ্ধতি মিথ্যা ফিরে আসবে।

আসুন আবার চেষ্টা করুন, খ শুধুমাত্র এই সময় খ একটি রেফারেন্স হবে। লক্ষ্য করুন যে বস্তু আইডি উভয় ভেরিয়েবলের জন্য একই, কারণ তারা একই বস্তুর দিকে নির্দেশ করে।

a = "zen"
b = a

a.object_id  # Output: => 18637360
b.object_id  # Output: => 18637360

a.equal? b  # Output: => true

eql?

হাশ শ্রেণিতে, একল? এটি সমতা জন্য কী পরীক্ষা করতে ব্যবহৃত হয়। এটি ব্যাখ্যা করার জন্য কিছু ব্যাকগ্রাউন্ডের প্রয়োজন। গণনার সাধারণ প্রসঙ্গে, একটি হ্যাশ ফাংশন যে কোনও আকারের একটি স্ট্রিং (বা একটি ফাইল) নেয় এবং হ্যাশকোড নামক একটি নির্দিষ্ট স্ট্রিং বা পূর্ণসংখ্যার উত্পাদন করে, সাধারণত হ্যাশ হিসাবে পরিচিত to কিছু ব্যবহৃত হ্যাশকোড প্রকারগুলি হ'ল MD5, SHA-1 এবং CRC। এগুলি এনক্রিপশন অ্যালগরিদম, ডাটাবেস সূচীকরণ, ফাইল অখণ্ডতা যাচাইকরণ ইত্যাদিতে ব্যবহৃত হয়। কিছু প্রোগ্রামিং ভাষা যেমন রুবি, হ্যাশ টেবিল নামে একটি সংগ্রহের প্রকার সরবরাহ করে। হ্যাশ টেবিলগুলি অভিধানের মতো সংগ্রহ যা জোড়ায় ডেটা সংরক্ষণ করে, অনন্য কী এবং তার সাথে সম্পর্কিত মানগুলি নিয়ে। ফণা অধীনে, এই কীগুলি হ্যাশকোড হিসাবে সংরক্ষণ করা হয়। হ্যাশ টেবিলগুলি সাধারণত হ্যাশ হিসাবে উল্লেখ করা হয়। লক্ষ্য করুন কীভাবে হ্যাশকান শব্দটি হ্যাশকোড বা হ্যাশ টেবিলকে বোঝায়।

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

"meditation".hash  # Output: => 1396080688894079547
"meditation".hash  # Output: => 1396080688894079547
"meditation".hash  # Output: => 1396080688894079547

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

Symbol.instance_method(:hash).owner  # Output: => Kernel
Integer.instance_method(:hash).owner # Output: => Kernel

String.instance_method(:hash).owner  # Output: => String
Hash.instance_method(:hash).owner  # Output: => Hash

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

"zen".eql? "zen"    # Output: => true
# is the same as
"zen".hash == "zen".hash # Output: => true

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

2 == 2.0    # Output: => true
2.eql? 2.0    # Output: => false
2.hash == 2.0.hash  # Output: => false

কেস সমতা অপারেটর: ===

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

String === "zen"  # Output: => true
Range === (1..2)   # Output: => true
Array === [1,2,3]   # Output: => true
Integer === 2   # Output: => true

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

2.is_a? Integer   # Output: => true
2.kind_of? Integer  # Output: => true
2.instance_of? Integer # Output: => false

শেষ উদাহরণটি মিথ্যা হিসাবে প্রত্যাবর্তিত হয়েছে তা লক্ষ্য করুন কারণ 2 এর মতো পূর্ণসংখ্যাগুলি ফিক্সনাম বর্গের উদাহরণ, যা পূর্ণসংখ্যা শ্রেণীর একটি সাবক্লাস। ===, কি_এ? এবং উদাহরণ_ও? যদি পদটি প্রদত্ত শ্রেণীর বা কোনও উপশ্রেণীর উদাহরণ হয় তবে পদ্ধতিগুলি সত্য হয়। উদাহরণ_পথটি আরও কঠোর এবং কেবলমাত্র সত্যটি প্রত্যাবর্তন করে যদি বস্তুটি একটি সঠিক শ্রেণীর উদাহরণ, সাবক্লাস নয়।

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

কার্নেল.ইনস্ট্যান্স_মোথোড (: দয়া করে_আফ?) == কার্নেল.ইনস্ট্যান্স_মোথোড (: এটি_এ?) # আউটপুট: => সত্য

=== এর ব্যাপ্তি বাস্তবায়ন

যখন === অপারেটরকে একটি ব্যাপ্তি অবজেক্টে ডাকা হয়, ডানদিকে মান বামদিকে পরিসরের মধ্যে পড়ে তবে এটি সত্য হয়।

(1..4) === 3  # Output: => true
(1..4) === 2.345 # Output: => true
(1..4) === 6  # Output: => false

("a".."d") === "c" # Output: => true
("a".."d") === "e" # Output: => false

মনে রাখবেন যে === অপারেটর বাম-হাতের অবজেক্টের === পদ্ধতিটি আহ্বান করে। সুতরাং (১.৪.৪) === ((১.৪) এর সমান। === ৩. অন্য কথায়, বাম-হাতের ক্রিয়াকলাপটি নির্ধারণ করবে যে === পদ্ধতির প্রয়োগ কী হবে? বলা হয়, সুতরাং অপারেন্ড অবস্থানগুলি বিনিময়যোগ্য নয়।

=== এর রিজেপক্স বাস্তবায়ন

ডান দিকের স্ট্রিংটি বামে নিয়মিত প্রকাশের সাথে মিলে গেলে সত্যটি প্রত্যাবর্তন করে। / zen / === "আজ জাজেন অনুশীলন করুন" # আউটপুট: => সত্য # "আজ অনুশীলন জাজেন" এর মতো = = ~ / জেন /

ক্ষেত্রে / যখন বিবৃতিগুলিতে === অপারেটরের অন্তর্ভুক্ত ব্যবহার

এই অপারেটরটি কেস / যখন স্টেটমেন্টগুলি হুডের নীচেও ব্যবহৃত হয়। এটি এর সবচেয়ে সাধারণ ব্যবহার।

minutes = 15

case minutes
  when 10..20
    puts "match"
  else
    puts "no match"
end

# Output: match

উপরের উদাহরণে, যদি রুবি সুস্পষ্টভাবে ডাবল সমান অপারেটর (==) ব্যবহার করে থাকে তবে 10..20 পরিসীমাটি 15 এর মতো পূর্ণসংখ্যার সমান হিসাবে বিবেচিত হবে না They তারা মিলছে কারণ ট্রিপল সমান অপারেটর (===) হয় স্পষ্টভাবে সমস্ত ক্ষেত্রে / যখন বিবৃতি ব্যবহার করা হয়। উপরের উদাহরণে কোডটি সমান:

if (10..20) === minutes
  puts "match"
else
  puts "no match"
end

প্যাটার্ন ম্যাচিং অপারেটর: = ~ এবং! ~ ~

রেগেক্স প্যাটার্নগুলির বিপরীতে স্ট্রিং এবং চিহ্নগুলির সাথে ম্যাচ করার জন্য = ~ (সমান তিল্ড) এবং! Opera (ব্যাং-টিলডে) অপারেটরগুলি ব্যবহৃত হয়।

স্ট্রিং এবং সিম্বল ক্লাসে = ~ পদ্ধতির প্রয়োগটি একটি নিয়মিত অভিব্যক্তি (রিজেক্সপ্স শ্রেণীর উদাহরণ) হিসাবে আর্গুমেন্ট হিসাবে প্রত্যাশা করে।

"practice zazen" =~ /zen/   # Output: => 11
"practice zazen" =~ /discursive thought/ # Output: => nil

:zazen =~ /zen/    # Output: => 2
:zazen =~ /discursive thought/  # Output: => nil

Regexp শ্রেণিতে প্রয়োগটি আর্গুমেন্ট হিসাবে একটি স্ট্রিং বা প্রতীক প্রত্যাশা করে।

/zen/ =~ "practice zazen"  # Output: => 11
/zen/ =~ "discursive thought" # Output: => nil

সমস্ত বাস্তবায়নে, যখন স্ট্রিং বা প্রতীকটি রেজিপ্লেক্স প্যাটার্নের সাথে মেলে, এটি একটি পূর্ণসংখ্যা দেয় যা ম্যাচের অবস্থান (সূচক)। কোনও মিল না থাকলে এটি শূন্য করে। মনে রাখবেন যে, রুবিতে, কোনও পূর্ণসংখ্যা মান "সত্যবাদী" এবং শূন্যস্থানটি "মিথ্যা" হয়, সুতরাং বিবরণী এবং টের্নারি অপারেটর যদি = ~ অপারেটরটি ব্যবহার করতে পারেন।

puts "yes" if "zazen" =~ /zen/ # Output: => yes
"zazen" =~ /zen/?"yes":"no" # Output: => yes

প্যাটার্ন-ম্যাচিং অপারেটরগুলি বিবৃতি স্বল্প লেখার জন্যও দরকারী। উদাহরণ:

if meditation_type == "zazen" || meditation_type == "shikantaza" || meditation_type == "kinhin"
  true
end
Can be rewritten as:
if meditation_type =~ /^(zazen|shikantaza|kinhin)$/
  true
end

! ~ অপারেটর = ~ এর বিপরীত, কোনও ম্যাচ না থাকলে এটি সত্য এবং মিথ্যা প্রমাণিত হয়।

আরও তথ্য এই ব্লগ পোস্টে উপলব্ধ


6
আমি এটি বর্তমানে গৃহীত উত্তরের চেয়ে ভাল উত্তর খুঁজে পাচ্ছি, কারণ এটি দুর্দান্ত উদাহরণ সরবরাহ করে এবং বিভিন্ন ধরণের সাম্যতা কী বোঝায় এবং সেগুলি কেন বিদ্যমান / যেখানে তারা ব্যবহৃত হয় সে সম্পর্কে কমই দ্ব্যর্থহীন।
কিউকিউই

1
খুব বিশদ উত্তর, তবে আমার আইআরবিতে (রুবি বনাম 2.2.1) :zen === "zen"মিথ্যা প্রত্যাবর্তন করে
মাইকে আর

@ মাইকআর আমাকে জানানোর জন্য আপনাকে ধন্যবাদ আমি উত্তরটি সংশোধন করেছি।
ব্রুনোফ্যাকা

আমার মনে হয় আপনি টাইপ_ মানে? "লক্ষ করুন শেষ উদাহরণটি ভুল হিসাবে ফিরে এসেছে কারণ 2 এর মতো পূর্ণসংখ্যাগুলি ফিক্সনাম বর্গের উদাহরণ, যা পূর্ণসংখ্যা শ্রেণীর একটি উপক্লাস The
ব্যবহারকারী 1883793

1
আমি এই উত্তর ভালবাসি। ধন্যবাদ
আব্দুল্লাহ ফাদেল

9

সাম্য সামলানোর জন্য রুবি বিভিন্ন ধরণের পদ্ধতি প্রকাশ করেছেন:

a.equal?(b) # object identity - a and b refer to the same object

a.eql?(b) # object equivalence - a and b have the same value

a == b # object equivalence - a and b have the same value with type conversion.

নীচের লিঙ্কটি ক্লিক করে পড়া চালিয়ে যান, এটি আমাকে একটি স্পষ্ট সংক্ষিপ্ত বোঝাপড়া দিয়েছে।

https://www.relishapp.com/rspec/rspec-expectations/v/2-0/docs/matchers/equality-matchers

আশা করি এটি অন্যকে সহায়তা করবে।


8

=== # --- কেস সমতা

== # --- জেনেরিক সমতা

উভয়ই একই রকম কাজ করে তবে "===" এমনকি কেস স্টেটমেন্টও করে

"test" == "test"  #=> true
"test" === "test" #=> true

এখানে পার্থক্য

String === "test"   #=> true
String == "test"  #=> false

3
তারা একইভাবে কাজ করে না , যদিও এটি সত্য হতে থাকে যখন a==bতখন a===b। তবে a===bঅনেক বেশি শক্তিশালী। ===প্রতিসম নয়, এবং a===bথেকে খুব ভিন্ন জিনিস মানে b===a, একা থাকতে দাও a==b
mwfearnley

8

আমি ===অপারেটরের উপর প্রসারিত করতে চাই ।

=== সমতা অপারেটর না!

না.

আসুন সত্য যে পয়েন্ট পেতে।

আপনার সাথে পরিচিত হতে পারেন === জাভাস্ক্রিপ্ট এবং পিএইচপি-তে সমতা অপারেটর হিসাবে , তবে এটি কেবল রুবির কোনও সমতা অপারেটর নয় এবং মূলত বিভিন্ন শব্দার্থক শব্দ রয়েছে।

তাহলে কি করে ===?

=== প্যাটার্ন ম্যাচিং অপারেটর!

  • === নিয়মিত প্রকাশের সাথে মেলে
  • === পরিসরের সদস্যপদ পরীক্ষা করে
  • === একটি শ্রেণীর উদাহরণ চেক
  • === ল্যাম্বদা এক্সপ্রেশন কল
  • === কখনও কখনও সমতা পরীক্ষা করে, তবে বেশিরভাগ ক্ষেত্রে তা হয় না

তাহলে এই উন্মাদনাটি কীভাবে বোঝায়?

  • Enumerable#grep===অভ্যন্তরীণভাবে ব্যবহার করে
  • case when বিবৃতি ব্যবহার === অভ্যন্তরীণভাবে
  • মজাদার ঘটনা, অভ্যন্তরীণভাবে rescueব্যবহার ===করে

এজন্য আপনি নিয়মিত এক্সপ্রেশন এবং ক্লাস এবং ব্যাপ্তি এবং এমনকি ল্যাম্বদা এক্সপ্রেশন ব্যবহার করতে পারেন এ case when বিবৃতিতে ।

কিছু উদাহরণ

case value
when /regexp/
  # value matches this regexp
when 4..10
  # value is in range
when MyClass
  # value is an instance of class
when ->(value) { ... }
  # lambda expression returns true
when a, b, c, d
  # value matches one of a through d with `===`
when *array
  # value matches an element in array with `===`
when x
  # values is equal to x unless x is one of the above
end

এই সমস্ত উদাহরণ pattern === valueখুব একই সাথে grepপদ্ধতি হিসাবে কাজ করে ।

arr = ['the', 'quick', 'brown', 'fox', 1, 1, 2, 3, 5, 8, 13]
arr.grep(/[qx]/)                                                                                                                            
# => ["quick", "fox"]
arr.grep(4..10)
# => [5, 8]
arr.grep(String)
# => ["the", "quick", "brown", "fox"]
arr.grep(1)
# => [1, 1]

-8

আমি উপরের সমস্তটির জন্য একটি সাধারণ পরীক্ষা লিখেছি।

def eq(a, b)
  puts "#{[a, '==',  b]} : #{a == b}"
  puts "#{[a, '===', b]} : #{a === b}"
  puts "#{[a, '.eql?', b]} : #{a.eql?(b)}"
  puts "#{[a, '.equal?', b]} : #{a.equal?(b)}"
end

eq("all", "all")
eq(:all, :all)
eq(Object.new, Object.new)
eq(3, 3)
eq(1, 1.0)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.