Перевірте, чи є змінною рядок у Ruby


Відповіді:


205

Я думаю, ти шукаєш instance_of?. is_a?і kind_of?поверне true для примірників похідних класів.

class X < String
end

foo = X.new

foo.is_a? String         # true
foo.kind_of? String      # true
foo.instance_of? String  # false
foo.instance_of? X       # true

9
Не знаючи наміру питання, я б сказав, що для більшості ситуацій програмування в реальному світі, is_a?насправді є більш прийнятною ідіомою (і часто перевірка набору качок, як згадує Ендрю Грімм, ще краща). Суворе порівняння класів зазвичай кодовий запах. en.wikipedia.org/wiki/Liskov_substitution_principle
mahemoff

Швидкий бік: якщо ви використовуєте це в умовної логіці, вам потрібно використовувати круглі дужки; наприклад, якщо foo.is_a? (String) && ...
дан

Як очікується, такий підхід буде працювати не тільки з String, але і з Integerі Float. Це також працює Decimal? (Піднесена текст перекладач підкреслює синтаксис по- різному для Decimalщо робить мене підозрілим)
stevec

29

Більш сказати було б підхід щодо набору качок

foo.respond_to?(:to_str)

to_str вказує на те, що клас об'єкта може бути не фактичним нащадком String, але сам об'єкт дуже схожий на рядок (stringy?).


Класно. В цьому випадку я знаю , що fooбуде або true, falseабо рядок ванілі, але це добре , щоб дізнатися більше спільні рішення.
davidchambers

поєднайте це з викликом to_s після перевірки, чи відповідає об'єкт_на нього, і ви отримали собі рядок!
seanmakesgames

1
@seanmakesgames Ви мали на увазі to_str, чи to_s? Два трохи відрізняються.
Ендрю Грімм


23

Ви можете зробити:

foo.instance_of?(String)

І більш загальне:

foo.kind_of?(String)

4
Що робить kind_ofбільш загальним? Вони здаються синонімами: is_a.
davidchambers

2
@Davidchambers ви маєте рацію, "kind_of?" є синонімом 'is_a?'.
steenslag

@davidchambers: Ти правий, я мав на увазі instance_of?замість цього is_a?.
Федеріко Буйлес

7
foo.instance_of? String

або

foo.kind_of? String 

якщо вам байдуже лише те, якщо воно походить Stringзвідкись у його ланцюжку спадкування


4

На додаток до інших відповідей, клас визначає метод === для перевірки того, чи є об'єкт екземпляром цього класу.

  • o.class клас о.
  • o.instan_of? c визначає, чи o.class == c
  • o.is_a? c Це o екземпляр c або будь-який його підклас?
  • o.kind_of? c синонімом * is_a? *
  • c === o для класу чи модуля, визначте, чи * o.is_a? c * ( рядок === "s" повертає істину)

-1

Я думаю, що кращим способом є створення деяких предикатних методів. Це також збереже вашу "Єдину точку управління".

class Object
 def is_string?
   false
 end
end

class String
 def is_string?
   true
 end
end

print "test".is_string? #=> true
print 1.is_string?      #=> false

Тим більше качка набирає спосіб;)


2
що сталося з "string".is_a?(String). Схоже, ви винаходите колесо. Там же class, instance_of, kind_ofі т.д. ... Погана ідея для мавпи патча Objectкласу, не кажучи вже про його зайвий.
Мохамад

Я повністю з вами погоджуюся :) Якщо ви зосереджуєтесь лише на типах примітів, і ви знаєте, що ваші вимоги до проекту, пов'язані з примітивними типами, ніколи не зміняться (нормально, як правило, це так;)) у вас все добре. Але у випадку, коли вимоги змінюються, краще мати "Єдину точку контролю". Наприклад, у проектному середовищі у вас є багато попередніх перевірок (від 1000 і вище). pre_check("test".is_string?) Тепер ваша вимога проекту зміниться, і кожен рядок з трьома символами або більше більше не визначається як String (я знаю його незвичайність;)) Тепер ви можете легко змінити власний метод.
schlegel11
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.