в первый раз при переполнении стека.
Я изучаю использование некоторых функций метапрограммирования, обеспеченных Ruby или Python, но сначала я должен знать степень, до которой они позволят мне расширять язык. Главное, которое я должен смочь сделать, состоит в том, чтобы переписать понятие Класса. Это не означает, что я хочу переписать определенный класс в течение времени выполнения, а скорее я хочу сделать свое собственное осмысление того, каков Класс. Чтобы быть smidge более определенным здесь, я хочу сделать что-то, что похоже на то, что люди обычно называют Классом, но я хочу следовать за "открытым мировым" предположением. В "закрытом мире" нормальных Классов, если я объявляю, что Пудель подкласс Собаки, чтобы быть подклассом Животного, затем я знаю, что Пудель не собирается также быть типом FurCoat. Однако в открытом мировом классе, затем Пудель возражает, что я определил, может или может не быть и объект типа FurCoat, и мы не будем знать наверняка, пока я не объясню, что могу носить пуделя. (Плохой пудель.) Это все имеет отношение к исследованию, я делаю касающиеся OWL-онтологии.
Именно так Вы знаете, я попытался найти информацию онлайн, но из-за перегрузки условий здесь я ничто не нашел полезным.
Супер спасибо, John
ОБНОВЛЕНИЕ: Я просто думал о хорошем варианте использования для своего открыто-мирового понятия Класса. Возможно, это обеспечит лучшее понимание того, что я действительно хочу сделать. Я хочу смочь "описать" Класс, а не определить его. Например, я хочу смочь сказать, что Собака - что-либо, что a) имеет четыре участка b) кора. Затем я хочу смочь создать объект неуказанного Класса и описать, что этот объект имеет четыре участка. В этой точке объект все еще имеет неуказанный тип. Затем я хочу сказать, что объект лает. На данном этапе объект, как будет известно, будет (возможно среди прочего) Собакой.
Я согласен с Самиром в том, что это похоже на утиную печать. Вам не нужно заботиться о том, какой «тип» на самом деле представляет собой объект, вам нужно беспокоиться только о том, что объект может «делать». Это верно как для Ruby, так и для Python.
Однако, если вы действительно проверяете типы классов и вам действительно нужно, чтобы объект Poodle
, возможно, также был FurCoat
во время выполнения, то способ сделать это Ruby должен подмешать модуль FurCoat
к объекту Poodle
следующим образом:
class Poodle; end
module FurCoat; def wear; end; end
my_poodle = Poodle.new
my_poodle.is_a?(Poodle) #=> true
my_poodle.is_a?(FurCoat) #=> false
my_poodle.wear #=> NoMethodError
# now we mix in the FurCoat module
my_poodle.extend(FurCoat)
# my_poodle is now also a FurCoat
my_poodle.is_a?(Poodle) #=> true (still)
my_poodle.is_a?(FurCoat) #=> true
my_poodle.wear #=> the wear method now works
ИЗМЕНИТЬ (из-за вашего обновленного вопроса):
Вам все еще не нужно чтобы переписать класс
для достижения желаемого, вам просто нужно исправить kind_of?
и is_a?
(и, возможно, instance_of?
]) в модуле Ruby Kernel
. Поскольку в Ruby есть открытые классы, это легко сделать:
class Module
def obj_implements_interface?(obj)
false
end
end
module Kernel
alias_method :orig_is_a?, :is_a?
def is_a?(klass)
orig_is_a?(klass) || klass.obj_implements_interface?(self)
end
end
А затем определите для каждого класса (или модуля), что означает для объекта реализовать свой интерфейс:
class Dog
def self.obj_implements_interface?(obj)
obj.respond_to?(:bark) && obj.respond_to?(:num_legs) && obj.num_legs == 4
end
end
module FurCoat
def self.obj_implements_interface?(obj)
obj.respond_to?(:wear)
end
end
Теперь протестируйте его:
my_poodle = Poodle.new
my_poodle.is_a?(FurCoat) #=> false
# now define a wear method on my_poodle
def my_poodle.wear; end
my_poodle.is_a?(FurCoat) #=> true
Я думаю, что полагаться на структуру классов, какой бы динамичной она ни была, - это шаг назад при представлении информации с открытым текстом.
Классы, служащие шаблонами, и объекты, служащие экземплярами, не дают абсолютно никаких преимуществ при использовании с OWA. Рассмотрим класс Person, в котором мы кодируем информацию о том, что у человека две ноги. Однако мы не можем сделать вывод, что у экземпляра Person будет две ноги, поскольку у человека может быть инвалидность.
Если свойства класса ничего не значат, как в приведенном выше примере, не имеет смысла использовать их или любую другую иерархическую структуру для кодирования информации.
Похоже, утка печатает для меня. Просто объявите методы, которые вам нужны, и помните, что проще попросить прощения, чем разрешения:
try:
poodle.wear()
except (AttributeError, TypeError):
pass
В Python вы можете изменить наследование класса во время выполнения, но в каждый момент времени класс не является подклассом другого класса, если не объявлено иное. Нет никаких "может или не может" - для этого нужна троичная логика, которую Python не поддерживает. Но, конечно, вы можете написать свои собственные функции "Is-a" и "Has-a" для отображения онтологий OWL на классы Python.
Нет, вы не можете сделать это в Ruby .В Ruby объектная модель встроена в спецификацию языка и недоступна (и уж точно не изменяема ) из программы. Даже в Rubinius , который является реализацией Ruby, написанной в основном на Ruby, и с удивительными возможностями метапрограммирования, которые выходят далеко за рамки того, что предлагает спецификация Ruby, некоторые из фундаментальных примитивов встроены в C ++ .
Я не очень хорошо знаком с Python , но я почти уверен, что это так же, даже в PyPy .
Вы можете сделать это в Smalltalk , изменив (или создав подкласс) класс Behavior
, который является суперкласс Class
и определяет поведение как классов, так и метаклассов.
Вы можете , конечно, сделать это в CLOS , или, точнее, используя MOP CLOS ( Протокол метаобъектов ). В конце концов, для этого и предназначена MOP: для определения объектной модели.
Наиболее близкой объектно-ориентированной концепцией к тому, что вы описываете, по-видимому, является Классы предикатов . Класс предикатов - это класс, экземпляры которого определяются не статически, а набором предикатов: все объекты, удовлетворяющие набору предикатов, являются экземплярами класса, как только предикат сохраняется. В языке с изменяемым состоянием это, очевидно, означает, что объекты могут «перемещаться» в классы предикатов и выходить из них при изменении их состояния.Это также означает, что в любой момент времени объект может быть экземпляром многих классов предикатов или ни одного.
Единственный известный мне мейнстримный язык (для довольно широкого определения «мэйнстрима»), имеющий классы предикатов, - это Factor .
Однако обратите внимание, что даже здесь предикаты определены, и объект либо выполняет их, либо нет. Не существует концепции определения того, выполняет ли объект предикат во время выполнения.
Возможно, вас заинтересует идея Clojure о специальной таксономии .
И последнее, но не менее важное: вы можете взглянуть на объектную систему Микеля Эвинса , которая называется Категории . Лучшее описание категорий - просто следить за записями в блоге в хронологическом порядке:
В будущем большая часть разработки категорий будет сделано на новом языке Микеля Bard , и вы можете следить за их прогрессом, следуя тегу Categories и тегу Bard в новом блоге Mikel .
Однако в целом я бы сказал, что тот факт, что в управлении знаниями и объектной ориентации используется слово класс , в основном является исторической случайностью. Я не думаю, что моделирование одного с другим подходит.