কেন একটি রেজিএক্সপ্যাক্স বস্তুকে রুবিতে "মিথ্যা" বলে মনে করা হয়?


16

রুবির " সত্যতা " এবং " মিথ্যাচার " সম্পর্কে সর্বজনীন ধারণা রয়েছে ।

রুবি করে বুলিয়ান অবজেক্টের জন্য দুই নির্দিষ্ট ক্লাস আছে, TrueClassএবং FalseClass, বিশেষ ভেরিয়েবল দ্বারা প্রকাশ Singleton দৃষ্টান্ত দিয়ে trueএবং falseযথাক্রমে।

তবে সত্যতা এবং মিথ্যাচার এই দুটি শ্রেণীর উদাহরণের মধ্যেই সীমাবদ্ধ নয়, ধারণাটি সর্বজনীন এবং রুবির প্রতিটি বস্তুর ক্ষেত্রে প্রযোজ্য। প্রতিটি বস্তু হয় সত্যবাদী বা মিথ্যা । নিয়ম খুব সহজ। বিশেষত, মাত্র দুটি বস্তু মিথ্যা :

  • nil, এর একক উদাহরণ NilClassএবং
  • falseএর একক উদাহরণ FalseClass

প্রতি একক অন্যান্য বস্তু হল truthy । এটি এমনকি অন্যান্য প্রোগ্রামিং ভাষায় যেমন মিথ্যা বলে বিবেচিত হয় এমন বস্তুগুলিও অন্তর্ভুক্ত করে

এই বিধিগুলি ভাষায় নির্মিত এবং ব্যবহারকারী-সংজ্ঞাযোগ্য নয়। কোনও to_boolঅন্তর্নিহিত রূপান্তর বা অনুরূপ কিছু নেই।

এখানে আইএসও রুবি ভাষার নির্দিষ্টকরণের একটি উদ্ধৃতি দেওয়া হয়েছে :

.6..6 বুলিয়ান মান

একটি বস্তু হয় একটি মধ্যে শ্রেণীবদ্ধ করা হয় trueish বস্তুর বা falseish বস্তুর

কেবল মিথ্যা এবং শূন্য মিথ্যা বস্তু। মিথ্যা হল শ্রেণীর একমাত্র উদাহরণ FalseClass(15.2.6 দেখুন), যেখানে মিথ্যা-এক্সপ্রেশন মূল্যায়ন করে (11.5.4.8.3 দেখুন)। শূন্য ক্লাসের শুধুমাত্র উদাহরণস্বরূপ হয় NilClass(15.2.4 দেখুন), যা করার জন্য একটি শূন্য প্রকাশ মূল্যায়ণ (11.5.4.8.2 দেখুন)।

মিথ্যা এবং শূন্য ব্যতীত অন্য বিষয়গুলি সত্যবাদী বস্তুগুলিতে শ্রেণিবদ্ধ করা হয়। সত্য হ'ল শ্রেণীর একমাত্র উদাহরণ TrueClass(15.2.5 দেখুন), যেখানে সত্য-অভিব্যক্তি মূল্যায়ন করে (11.5.4.8.3 দেখুন)।

এক্সিকিউটেবল রুবি / স্পেক সম্মত বলে মনে হচ্ছে :

it "considers a non-nil and non-boolean object in expression result as true" do
  if mock('x')
    123
  else
    456
  end.should == 123
end

ঐ দুই সূত্র মতে, আমি অনুমান যে Regexpগুলি রয়েছে truthy , কিন্তু আমার পরীক্ষা অনুযায়ী, তারা নয়:

if // then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are falsy'

আমি এটি YARV 2.7.0-পূর্বরূপ 1 , ট্রফলার রুবি 19.2.0.1 এবং জেআরবি 9.2.8.0 এ পরীক্ষা করেছি । তিনটি বাস্তবায়ন একে অপরের সাথে একমত এবং আইএসও রুবি ল্যাঙ্গুয়েজ স্পেসিফিকেশন এবং রুবি / স্পেক সম্পর্কে আমার ব্যাখ্যাটির সাথে একমত নয়।

আরো সঠিকভাবে, Regexpযে বস্তু মূল্যায়নের ফল Regexp লিটারেল হয় falsy , যেহেতু Regexpযে বস্তু অন্য কিছু অভিব্যক্তি ফল হয় truthy :

r = //
if r then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are truthy'

এটি কি কোনও বাগ, বা পছন্দসই আচরণ?


মজার বিষয় হ'ল Regex.new("a")সত্য।
মির্জা

!!//মিথ্যা তবে !!/r/সত্য। অদ্ভুত প্রকৃতপক্ষে.
সর্বাধিক

@ ম্যাক্স আমার জন্য (আরভিএম) রুবি ২.৪.১ ব্যবহার !!/r/করে উত্পাদন falseকরে।
3limin4t0r

দুঃখিত আমার খারাপ @ 3limin4t0r। তুমি ঠিক. আমি অবশ্যই একটি নির্বোধের চিহ্ন ছেড়ে দেওয়ার মতো সত্যিই বোকামি কিছু করেছি।
সর্বাধিক

2
থেকেই ধরে নেয়া যায়, আমি মনে করি যে //if // thenএকটি পরীক্ষা (জন্য শর্টকাট হিসাবে ব্যাখ্যা করা হয় if //=~nil thenএকটি RegExp উদাহরণস্বরূপ হিসেবে এবং না (যে সবসময় falsy যাই হোক না কেন প্যাটার্ন))।
ক্যাসিমির এবং

উত্তর:


6

এটি কোনও বাগ নয়। যা ঘটছে তা হ'ল রুবি কোডটি পুনরায় লিখছেন

if /foo/
  whatever
end

কার্যকরভাবে হয়ে ওঠে

if /foo/ =~ $_
  whatever
end

আপনি যদি এই কোডটি কোনও সাধারণ স্ক্রিপ্টে চালাচ্ছেন (এবং -eবিকল্পটি ব্যবহার করছেন না ) তবে আপনার একটি সতর্কতা দেখতে হবে:

warning: regex literal in condition

এটি সম্ভবত বেশিরভাগ সময় কিছুটা বিভ্রান্তিকর হয়, এ কারণেই সতর্কতা দেওয়া হয় তবে -eবিকল্পটি ব্যবহার করে একটি লাইনের জন্য কার্যকর হতে পারে । উদাহরণস্বরূপ আপনি একটি ফাইল থেকে একটি প্রদত্ত regexp এর সাথে মেলে সমস্ত লাইন মুদ্রণ করতে পারেন

$ ruby -ne 'print if /foo/' filename

(ডিফল্ট যুক্তি printহল $_হিসাবে ভাল।)


আরও দেখুন -n, -p, -aএবং -lঅপশন, সেইসাথে কার্নেল পদ্ধতির থাবা যে শুধুমাত্র উপলব্ধ হলে -nবা -pব্যবহৃত হয় ( chomp, chop, gsubএবং sub)।
ম্যাট

রয়েছে পার্সার একটি দ্বিতীয় অংশ যেখানে যে সতর্কবার্তা নির্গত হয়। আমি জানি না সেখানে কী চলছে।
ম্যাট

আমি বিশ্বাস করি যে "দ্বিতীয় ভাগ" হ'ল এটিই আসলে এই প্রশ্নের ক্ষেত্রে প্রযোজ্য। NODE_LITধরনের সঙ্গে T_REGEXP। আপনার উত্তরে আপনি যে পোস্ট করেছেন সেটি হ'ল গতিশীল Regexpআক্ষরিক , অর্থাত্ Regexpআক্ষরিক যা অন্তরঙ্গ ব্যবহার করে /#{''}/
Jörg ডব্লু মিটাগ

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

4

এটি রুবি ভাষার একটি অননুমোদিত বৈশিষ্ট্য (যতদূর আমি বলতে পারি) এর ফলাফল, যা এই স্পেস দ্বারা সর্বোত্তমভাবে ব্যাখ্যা করা হয়েছে :

it "matches against $_ (last input) in a conditional if no explicit matchee provided" do
  -> {
    eval <<-EOR
    $_ = nil
    (true if /foo/).should_not == true
    $_ = "foo"
    (true if /foo/).should == true
    EOR
  }.should complain(/regex literal in condition/)
end

আপনি সাধারণত মনে করতে পারেন $_হিসাবে "গত স্ট্রিং দ্বারা পড়া gets"

বিষয় আরও বেশি, বিভ্রান্তিকর করতে $_(সহ $-) হল না একটি বিশ্বব্যাপী পরিবর্তনশীল; এটির স্থানীয় সুযোগ রয়েছে


যখন একটি রুবি স্ক্রিপ্ট শুরু হয় $_ == nil,।

সুতরাং, কোড:

// ? 'Regexps are truthy' : 'Regexps are falsey'

এর মতো ব্যাখ্যা করা হচ্ছে:

(// =~ nil) ? 'Regexps are truthy' : 'Regexps are falsey'

... যা মিথ্যা প্রত্যাবর্তন করে।

অন্যদিকে, অ-আক্ষরিক regexp (যেমন r = //বা Regexp.new('')) এর জন্য, এই বিশেষ ব্যাখ্যাটি প্রযোজ্য নয়।

//সত্যবাদী; ঠিক তেমনি রুবিতে থাকা সমস্ত অন্যান্য বস্তুর মতো nilএবং false


কমান্ড লাইনে সরাসরি অর্থাত্ রুবি স্ক্রিপ্ট না চালানো (অর্থাত্ -eপতাকা সহ), রুবি পার্সার এই জাতীয় ব্যবহারের বিরুদ্ধে একটি সতর্কতা প্রদর্শন করবে:

সতর্কতা: শর্তে রেজেক্স আক্ষরিক

আপনি পারে ভালো কিছু সঙ্গে একটি স্ক্রিপ্টের মধ্যে এই আচরণ ব্যবহার করতে:

puts "Do you want to play again?"
gets
# (user enters e.g. 'Yes' or 'No')
/y/i ? play_again : back_to_menu

... তবে ফলাফলের জন্য একটি স্থানীয় ভেরিয়েবল নির্ধারণ করা getsএবং এই মানটির বিরুদ্ধে স্পষ্টভাবে রেজেক্স চেক সম্পাদন করা আরও স্বাভাবিক হবে।

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


আমি কেবল উদাহরণ হিসাবে শর্তসাপেক্ষ ব্যবহার করেছি। !// #=> trueএকই আচরণ এবং শর্তাধীন নয়। আমি কোনও বুলিয়ান প্রসঙ্গ খুঁজে পাইনি (শর্তসাপেক্ষে বা না), যেখানে এটি প্রত্যাশার সাথে আচরণ করে।
Jörg ডব্লু মিট্টাগ

@ JörgWMittag আপনি যেমন অর্থ !// ? true : falseআয় true? আমি আবার এটি একই পয়েন্ট মনে করি - এটি এর মতো ব্যাখ্যা করা হচ্ছে:!(// =~ nil) ? true : false
টম লর্ড

আপনি যদি $_ = 'hello world'উপরের কোডটি চালনার আগে ম্যানুয়ালি সেট করেন তবে আপনার আলাদা ফলাফল পাওয়া উচিত - কারণ // =~ 'hello world', তবে এটি মেলে না nil
টম লর্ড

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

2
আহ .. হ্যাঁ, খুব অবাক। আচরণটি লিঙ্কযুক্ত বলে মনে হচ্ছে, যদিও: puts !//; $_ = ''; puts !//- আমি মনে করি কারণ পার্সার এটি ম্যাক্রোর মতো প্রসারিত করে; এটি অগত্যা একটি শর্তসাপেক্ষে থাকা প্রয়োজন হয় না?
টম লর্ড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.