Smalltalk по-русски
вторник, Январь 04, 2005
Объект nil

В данной статье мы расскажем об особенностях объекта nil.

Сразу стоит отметить, что nil из Smalltalk и null в традиционных языках, это далеко не одно и то же. Ключевое слово nil ссылается на синглтон класса UndefinedObject, наследника Object. То есть, он является полноценным объектом и может отвечать на любые сообщения, для которых есть реализации в классах Object и UndefinedObject.

Такая реализация контрастирует с семейством C-подобных языков, где null или (void*)0 или (TYPE*)0 обозначает "ничто". Под этим определением не скрывается никакого реального объекта, оно лишь обозначает, что данное значение не содержит корректной ссылки на объект заданного типа и может участвовать лишь в проверках с другими ссылками. Таким образом переменную, содержащую null, можно использовать в качестве параметра, но никогда в качестве объекта-получателя сообщения, иначе возникнет NullPointerException либо неопределенное поведение.

То есть, фактически, каждая ссылочная переменная имеет тип не просто <Type>, а <Type | null>. Поэтому теоретически любая переменная может стать причиной исключения в отсутствие проверки вида

	if (var != null)

В частности, на практике часто возникает проблема при использовании следующей конструкции

	var1.equals(var2)

Хотя было бы логично, чтобы null соответствующим образом отвечал на сообщение equals, иначе приходится писать вот так

	var1 == var2 || (var1 != null && var1.equals(var2))

либо определить статический метод, реализующий данную проверку, либо гарантировать, что первая ссылка заведомо не содержит null.

Некоторые встроенные конструкции содержат обход указанной проблемы, например

	var instanceof SomeClass

Данный оператор уже содержит встроенную проверку на null, но этот прием доступен только разработчикам языка.

Поэтому становится очевидным почему оператор instanceof (и ряд других) не может быть реализован в таком виде как метод экземпляра класса Object. Одна нелогичность явилась результатом появления других.

Но вернемся опять к Smalltalk и объекту nil. Так как UndefinedObject является прямым наследником Object, то он содержит всю базовую функциональность, его можно использовать в выражениях, и как параметр, и как получатель сообщения.

Например эти вызовы являются безопасными:

	nil = nil                вернет true 
	nil = 'a string'         вернет false 
	nil class                вернет UndefinedObject 
	nil printString          вернет 'nil' 

В некотором смысле Smalltalk является более "безопасным" по отношению к языкам, в которых любое обращение к null вызывает исключение.

Благодаря этому также возникла идиома, по которой сама проверка заменяется на сообщение:

	self someCondition isNil ifTrue: [...]

	nil isNil                вернет true 
	nil notNil               вернет false 

	Object new isNil         вернет false 
	Object new notNil        вернет true 

Также стало возможным реализовать упрощенную условную конструкцию (как всегда, в виде обычного метода), заменяющую проверку на nil:

	result := self someCondition
		    ifNil:    ['nil value']
	            ifNotNil: [:obj | 'non-nil value: ' , obj printString]

Например, следующим образом может быть реализован Singleton:

Singleton class>>instance
	^instance ifNil: [instance := self new]

ВЫВОДЫ

Данная статья демонстрирует то, как язык, построенный на минимальном количестве базовых концепций, доступных в одинаковой мере и создателям языка и разработчикам, порождает однородный дизайн с предсказуемым поведением. В данном случае, даже такое обособленное понятие, как nil, ничем особенным не выделяется (кроме его специфической роли на уровне VM как начальное значение неинициализированных данных) и повинуется общим правилам для всех остальных объектов. Меньшее количество частных случаев дает большие возможности для разработчика, большую предсказуемость, а значит безопасность.

По данной теме у нас на сайте уже имеется статья, описывающее возможное изменение семантики обычного языка для поддержки полноценного объекта null - Null Considered Harmful?

Также имеется перевод статьи Обобщенный паттерн <Null Object>, в которой рассматривается реализация Null Object, "поедающая" сообщения.

Comments: Отправить комментарий

<< Home

Популярные статьи
:: Smalltalk?!
:: Почему Smalltalk?
:: Great Leap Forward from Java to Smalltalk

Последние сообщения
:: smalltalk@wikipedia
:: Smalltalk Solutions
:: Use continuations to develop complex Web applicati...
:: Bottom line '2004
:: BowlingGame in Smalltalk
:: VisualWorks Smalltalk 7.3 NC and ObjectStudio 7.0 ...
:: Настройка VisualWorks Smalltalk
:: Smalltalk & grid computing
:: Smalltalk video

Архив
Предыдущие новости / Декабрь 2004 / Январь 2005 / Февраль 2005 / Март 2005 / Апрель 2005 / Май 2005 / Июнь 2005 / Июль 2005 / Август 2005 / Сентябрь 2005 / Октябрь 2005 / Ноябрь 2005 / Декабрь 2005 / Январь 2006 / Февраль 2006 / Март 2006 / Апрель 2006 / Май 2006 / Июнь 2006 / Июль 2006 / Сентябрь 2006 / Октябрь 2006 / Ноябрь 2006 / Декабрь 2006 / Январь 2007 / Февраль 2007 / Март 2007 / Апрель 2007 / Май 2007 / Июнь 2007 / Август 2007 / Сентябрь 2007 / Ноябрь 2007 / Январь 2008 / Март 2008 / Май 2008 / Июнь 2008 / Июль 2008 / Август 2008 / Сентябрь 2008

Atom Feed
Smalltalk по-русски


Powered by Blogger