Какова цель NilClass, TrueClass и FalseClass - PullRequest
6 голосов
/ 06 ноября 2011

NilClass, TrueClass и FalseClass с одним экземпляром каждый, а именно nil, true и false, которые являются константами, какова цель наличия этих классов?Почему они не могут быть экземплярами класса Object, а все соответствующие методы просто определяются как одноэлементные методы в nil, true и false?Смежный вопрос: почему они не определены как константы?

Ответы [ 2 ]

11 голосов
/ 06 ноября 2011

Это соответствует идее, что «все является объектом» и «объекты специализируются по классам, экземплярами которых они являются».

nil, true и false являются объектами (и, следовательно, являются экземплярами класса с методами). Утверждение, что они 1) являются единственными обитателями соответствующего типа и 2) неизменяемыми объектами , что позволяет оптимизировать реализацию - и действительно, разве one nil недостаточно?

Полезное сообщение об ошибке без специализации для значений: x.class "просто работает".

> > nil.foo
> => #<NoMethodError: undefined method `foo' for nil:NilClass>

Я рад, что сказал NilClass: -)

Этот подход к экземпляру класса также делает повторное открытие NilClass - в лучшую или в худшую сторону - настолько простым и совместимым с тем, как это можно сделать для других типов.

По крайней мере, в Ruby 1.9.2 невозможно переназначить true, false или nil (Python 2.x допускает переназначение True / False, но не в Python 3 .Икс). Обратите внимание, что поскольку true/false/nil являются не константами, их можно оптимизировать в AST - или что бы то ни было в реализации - как "буквальные значения" без постоянного поиска.

> > VERSION
> => "1.9.2"
> > true = false­
> => #<SyntaxError: Can't change the value of true>
> > [].each {|tru­e|}
> => #<SyntaxError: Can't change the value of true>

Удачного кодирования.

1 голос
/ 07 ноября 2011

В Ruby иногда используется принцип «просто возьмите объект и добавьте к нему несколько одноэлементных методов»:

C:\Documents and Settings\a.grimm>irb
irb(main):001:0> self.methods - Object.new.methods

дает

[: public,: private,: include,: context,: conf,: irb_quit,: exit, : quit,: irb_print_working_workspace,: irb_cwws,: irb_pwws,: cwws, : pwws,: irb_current_working_binding,: irb_print_working_binding, : irb_cwb,: irb_pwb,: irb_chws,: irb_cws,: chws,: cws, : irb_change_binding,: irb_cb,: cb,: рабочие пространства,: irb_bindings, : привязки,: irb_pushws,: pushws,: irb_push_binding,: irb_pushb, : pushb,: irb_popws,: popws,: irb_pop_binding,: irb_popb,: popb, : source,: jobs,: fg,: kill,: help,: irb_exit,: irb_context, : install_alias_method,: irb_current_working_workspace, : irb_change_workspace,: irb_workspaces,: irb_push_workspace, : irb_pop_workspace,: irb_load,: irb_require,: irb_source,: irb, : irb_jobs,: irb_fg,: irb_kill,: irb_help]

Я не знаю, почему они не делают такой подход с true, false или nil. Может быть, потому что людям нужно понимать эти объекты (согласно ответу pst), тогда как людям не нужно понимать «главный» (?) Объект.

...