В Ruby или Python может самое понятие Класса быть переписанным?

в первый раз при переполнении стека.

Я изучаю использование некоторых функций метапрограммирования, обеспеченных Ruby или Python, но сначала я должен знать степень, до которой они позволят мне расширять язык. Главное, которое я должен смочь сделать, состоит в том, чтобы переписать понятие Класса. Это не означает, что я хочу переписать определенный класс в течение времени выполнения, а скорее я хочу сделать свое собственное осмысление того, каков Класс. Чтобы быть smidge более определенным здесь, я хочу сделать что-то, что похоже на то, что люди обычно называют Классом, но я хочу следовать за "открытым мировым" предположением. В "закрытом мире" нормальных Классов, если я объявляю, что Пудель подкласс Собаки, чтобы быть подклассом Животного, затем я знаю, что Пудель не собирается также быть типом FurCoat. Однако в открытом мировом классе, затем Пудель возражает, что я определил, может или может не быть и объект типа FurCoat, и мы не будем знать наверняка, пока я не объясню, что могу носить пуделя. (Плохой пудель.) Это все имеет отношение к исследованию, я делаю касающиеся OWL-онтологии.

Именно так Вы знаете, я попытался найти информацию онлайн, но из-за перегрузки условий здесь я ничто не нашел полезным.

Супер спасибо, John

ОБНОВЛЕНИЕ: Я просто думал о хорошем варианте использования для своего открыто-мирового понятия Класса. Возможно, это обеспечит лучшее понимание того, что я действительно хочу сделать. Я хочу смочь "описать" Класс, а не определить его. Например, я хочу смочь сказать, что Собака - что-либо, что a) имеет четыре участка b) кора. Затем я хочу смочь создать объект неуказанного Класса и описать, что этот объект имеет четыре участка. В этой точке объект все еще имеет неуказанный тип. Затем я хочу сказать, что объект лает. На данном этапе объект, как будет известно, будет (возможно среди прочего) Собакой.

9
задан JnBrymn 23 June 2011 в 15:34
поделиться

5 ответов

Я согласен с Самиром в том, что это похоже на утиную печать. Вам не нужно заботиться о том, какой «тип» на самом деле представляет собой объект, вам нужно беспокоиться только о том, что объект может «делать». Это верно как для 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
7
ответ дан 4 December 2019 в 08:50
поделиться

Я думаю, что полагаться на структуру классов, какой бы динамичной она ни была, - это шаг назад при представлении информации с открытым текстом.

Классы, служащие шаблонами, и объекты, служащие экземплярами, не дают абсолютно никаких преимуществ при использовании с OWA. Рассмотрим класс Person, в котором мы кодируем информацию о том, что у человека две ноги. Однако мы не можем сделать вывод, что у экземпляра Person будет две ноги, поскольку у человека может быть инвалидность.

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

1
ответ дан 4 December 2019 в 08:50
поделиться

Похоже, утка печатает для меня. Просто объявите методы, которые вам нужны, и помните, что проще попросить прощения, чем разрешения:

try:
    poodle.wear()
except (AttributeError, TypeError):
    pass
8
ответ дан 4 December 2019 в 08:50
поделиться

В Python вы можете изменить наследование класса во время выполнения, но в каждый момент времени класс не является подклассом другого класса, если не объявлено иное. Нет никаких "может или не может" - для этого нужна троичная логика, которую Python не поддерживает. Но, конечно, вы можете написать свои собственные функции "Is-a" и "Has-a" для отображения онтологий OWL на классы Python.

2
ответ дан 4 December 2019 в 08:50
поделиться

Нет, вы не можете сделать это в Ruby .В Ruby объектная модель встроена в спецификацию языка и недоступна (и уж точно не изменяема ) из программы. Даже в Rubinius , который является реализацией Ruby, написанной в основном на Ruby, и с удивительными возможностями метапрограммирования, которые выходят далеко за рамки того, что предлагает спецификация Ruby, некоторые из фундаментальных примитивов встроены в C ++ .

Я не очень хорошо знаком с Python , но я почти уверен, что это так же, даже в PyPy .

Вы можете сделать это в Smalltalk , изменив (или создав подкласс) класс Behavior , который является суперкласс Class и определяет поведение как классов, так и метаклассов.

Вы можете , конечно, сделать это в CLOS , или, точнее, используя MOP CLOS ( Протокол метаобъектов ). В конце концов, для этого и предназначена MOP: для определения объектной модели.

Наиболее близкой объектно-ориентированной концепцией к тому, что вы описываете, по-видимому, является Классы предикатов . Класс предикатов - это класс, экземпляры которого определяются не статически, а набором предикатов: все объекты, удовлетворяющие набору предикатов, являются экземплярами класса, как только предикат сохраняется. В языке с изменяемым состоянием это, очевидно, означает, что объекты могут «перемещаться» в классы предикатов и выходить из них при изменении их состояния.Это также означает, что в любой момент времени объект может быть экземпляром многих классов предикатов или ни одного.

Единственный известный мне мейнстримный язык (для довольно широкого определения «мэйнстрима»), имеющий классы предикатов, - это Factor .

Однако обратите внимание, что даже здесь предикаты определены, и объект либо выполняет их, либо нет. Не существует концепции определения того, выполняет ли объект предикат во время выполнения.

Возможно, вас заинтересует идея Clojure о ​​специальной таксономии .

И последнее, но не менее важное: вы можете взглянуть на объектную систему Микеля Эвинса , которая называется Категории . Лучшее описание категорий - просто следить за записями в блоге в хронологическом порядке:

  1. Протоколы
  2. Категории
  3. Взгляд на Категории
  4. Без королей в Риме
  5. Появляется разумное их факсимиле
  6. ] Различные категории категорий
  7. Категории Ошибки
  8. Плоский кот в цистерне C3
  9. Категории 0,2
  10. Бард
  11. Бард хитрости

В будущем большая часть разработки категорий будет сделано на новом языке Микеля Bard , и вы можете следить за их прогрессом, следуя тегу Categories и тегу Bard в новом блоге Mikel .

Однако в целом я бы сказал, что тот факт, что в управлении знаниями и объектной ориентации используется слово класс , в основном является исторической случайностью. Я не думаю, что моделирование одного с другим подходит.

6
ответ дан 4 December 2019 в 08:50
поделиться