В чем разница между Class и Klass в рубине?

113

В чем разница между Class и Klass?

thenengah
источник
1
Где вы видели последнее?
Дарин Димитров
18
klassобычно используется для наименования переменной, содержащей Classобъект (помните, что классы тоже являются объектами), например klass = String. Можете ли вы указать источник того, где вы это видели, для более глубокого объяснения?
Чубас
5
Нет, я не хочу предоставлять единый источник, потому что не хочу, чтобы это объяснялось так. Я хочу получить более крупную картину об этом
thenengah
5
Иногда люди используют clazzвместо klass(например, в книге «Метапрограммирование Ruby»).
Эндрю Гримм
2
В TV Tropes это будет называться «Xtreme Kool Letterz» (без ссылки - небезопасно для продуктивности).
Эндрю Гримм

Ответы:

189

classключевое слово, используемое для определения нового класса. Поскольку это зарезервированное ключевое слово, вы не можете использовать его в качестве имени переменной. Вы не можете использовать какие-либо ключевые слова Ruby в качестве имен переменных, поэтому вы не сможете иметь переменные с именами defили moduleили ifили endи т. Д. - classне исключение.

Например, рассмотрим следующее:

def show_methods(class)
  puts Object.const_get(class).methods.inspect
end
show_methods "Kernel"

Попытка запустить это приводит к ошибке, так как вы не можете использовать classв качестве имени переменной.

test.rb:1: syntax error, unexpected kCLASS, expecting ')'
    def show_methods(class)
                          ^
test.rb:2: syntax error, unexpected ')'
      puts Object.const_get(class).methods.inspect

Чтобы исправить это, мы будем использовать klassвместо этого идентификатор . Это не что-то особенное, но обычно используется как имя переменной, когда вы имеете дело с классом или именем класса. Фонетически это то же самое, но поскольку это не зарезервированное ключевое слово, у Ruby нет проблем с ним.

def show_methods(klass)
  puts Object.const_get(klass).methods.inspect
end

show_methods "Kernel"

Выход, как и ожидалось,

["method", "inspect", "name", "public_class_method", "chop!"...

Вы можете использовать здесь любое (незарезервированное) имя переменной, но сообщество приняло это за использование klass. В нем нет особой магии - это просто означает: «Я хотел использовать здесь имя« класс », но не могу, поскольку это зарезервированное ключевое слово».

Кстати, поскольку вы несколько раз напечатали его неправильно, стоит отметить, что в Ruby регистр имеет значение. Токены, начинающиеся с заглавной буквы, являются константами. С помощью кирки :

Имя константы начинается с заглавной буквы, за которой следуют символы имени. Имена классов и модулей являются константами и соответствуют соглашениям об именах констант. По соглашению, постоянные переменные обычно пишутся прописными буквами и подчеркиваниями.

Таким образом, правильное написание - classи klass, а не Classи Klass. Последнее были бы постоянными, как Classи Klassявляются допустимыми именами постоянных, но я бы не рекомендовал использовать их для ясности.

Крис Хилд
источник
7
Что ж, это не только Classдействительное имя константы, но и существующее! (это классный класс)
Ашера
1
Вау красивый. Полностью понимаю сейчас. Спасибо, Крис! :)
thenengah
1
Я думаю, что использование klassв качестве локальной переменной взято из Кирки - они использовали это имя в нескольких примерах именно по причинам, которые вы описали здесь.
Ken Bloom
При этом должна применяться старая рубиновая версия. Я использую Ruby 1.9.3object_instance.class.name == 'Object'
Августин Ридингер
Нет, все еще точно. Класс Object.new - это Object, а класс Object - это Class.
Крис Хилд,
23

klassтакже является методом Rails (или, скорее, ActiveRecord) . Он используется для получения класса ассоциации.

Как указано в связанном контенте:

class Author < ActiveRecord::Base
  has_many :books
end

Author.reflect_on_association(:books).klass
# => Book
DazBaldwin
источник
12

klassи clazzи claszи т.п. творческие опечаток , используемые , чтобы обойти зарезервированное слово class.

Было бы гораздо менее неприятно для глаз использовать class1или clили classXили что-то, а не намеренная орфографическая ошибка.

Джейсон С
источник
5

Один из них - это имя класса, а другой - просто неопределенная константа по умолчанию. И для пары, которую вы, скорее всего, увидите, classи klassпервое - это ключевое слово для определения классов, а второе - просто идентификатор (как и любая другая строка символов). Он используется, когда вы хотите написать слово «класс», но не можете, потому что это зарезервированное ключевое слово.

цыпленок
источник
В чем суть, я имею в виду, зачем / как его использовать, для чего обычно?
thenengah
3
@Sam class - зарезервированное ключевое слово для определения классов. Итак, если вы хотите иметь дело с универсальным классом (например, с метапрограммированием), вы не можете писать class = Kernel.const_get(class_name). Но вы можете писать klass = Kernel.const_get(class_name), и это используется для обозначения «класса».
Тьяго Силвейра
2
Дело в том, что вы не можете использовать ключевое слово «класс» для обозначения «класс» ... потому что это зарезервированное слово (круговая логика, я знаю), поэтому вместо него подставляется слово «класс». Это обычная идиома во многих других языках, например Java и C #.
Скотт
так вы можете динамически назначать класс? Klass = object.class; Klass.new - что-то в этом
роде
3
@Sam: Использование Klassдля этого было бы плохим выбором, поскольку идентификаторы, начинающиеся с заглавных букв, являются константами, поэтому вы можете установить его только один раз. Но да, это общая идея.
Чак