parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

Да, миксины штука хорошая...

Sumo 06.10.2015 15:49 / 06.10.2015 16:02

... и решает проблему с отсутствием множественного наследования в языке.


Накидал прототип:
@main[]
  $o[^my::create[]]
  ^o.print_var_1[]
  ^o.print_var_2[]
  ^o._inner_method[]

  $o2[^my::create[]]
  ^o2.print_var_1[]
  ^o2.print_var_2[]
  ^o2._inner_method[]

  ^print_fields[$o2]

# Динамический миксин
  $o3[^my2::create[]]
  ^mix2:include_mixin[$o3]
  $o3.var_1[value_3]
  ^o3.print_var_1[]
  ^o3.print_var_2[]
  ^print_fields[$o3]

@print_fields[aObj][locals]
  $f[^reflection:fields[$aObj]]
  ^f.foreach[k;_]{
    $k
  }


@CLASS
my

@create[]
  ^mix2:include_mixin[]
  ^mix3:include_mixin[]
  $var_1[value_1]


@CLASS
my2

@create[]



@CLASS
mix

# Базовый класс миксина

@auto[]
  $_RESERVED_MIXINS_NAMES_[
    $.include_mixin[]
    $.__init__[]
  ]

@static:include_mixin[aContainer][obj]
## aContainer[$caller.self] — если передали миксиним в объект, иначе берем self из caller'а.
  $result[]
  $obj[^reflection:create[$CLASS_NAME;__init__;^if(def $aContainer){$aContainer}{$caller.self}]]

@__init__[aThis;aOptions][locals]
## aOptions.includePrivate.bool(false) — включать методы, начинающиеся с подчеркивания
  $lIncludePrivate(^aOptions.includePrivate.bool(false))
  $self.this[$aThis]
  $lMethods[^reflection:methods[$CLASS_NAME]]
  ^lMethods.foreach[m;_]{
    ^if(^_RESERVED_MIXINS_NAMES_.contains[$m]
      || (!$lIncludePrivate && ^m.left(1) eq "_")
    ){
       ^continue[]
     }
    $this.[$m][$self.[$m]]
  }



@CLASS
mix2

# Делаем миксин с двумя методами и переменной var_2

@BASE
mix

@__init__[aThis]
  ^BASE:__init__[$aThis]
  $this.var_2[^math:uuid[]]

@print_var_1[]
  $result[$this.var_1]

@print_var_2[]
  $result[^_private_method[]$this.var_2]

@_private_method[]
  $result[value: ]



@CLASS
mix3

# Миксин с приватны методом.

@BASE
mix

@__init__[aThis;aOptions]
  ^BASE:__init__[$aThis;$.includePrivate(true)]
# Переменная миксина, которая недоступна в классе-доноре.
  $_mixin_var[mv: ^math:uuid[]]

@_inner_method[]
  $result[Inner method. ($_mixin_var)]
Миксин в этой реализации — специальный вариант класса. Для доступа к переменным класса-приемника используем переменную this вместо self.

Результат работы:
  value_1
  value: 1A979D6C-303F-4873-A9E6-85E5F3617950
  Inner method. (mv: 29B5BE9F-64D8-4C13-9632-924134EDF66D)

  value_1
  value: 34C6E147-6839-4F7B-B4BD-66586BFA752A
  Inner method. (mv: D09227D2-BEA1-4BDA-8A69-8D9869F5C4AE)

    print_var_1
    print_var_2
    var_2
    _inner_method
    var_1


  value_3
  value: 90F44B5C-27D7-4E40-A14C-C446AB528DE4

    print_var_1
    print_var_2
    var_2
    var_1
Выглядит очень прилично. Похоже пора PF2 делать на миксинах. :)