<commit_before>require 'uber/inheritable_attr'
require 'disposable/twin/representer'
require 'disposable/twin/option'
require 'disposable/twin/builder'

# Twin.new(model/composition hash/hash, options)
#   assign hash to @fields
#   write: write to @fields
#   sync/save is the only way to write back to the model.

module Disposable
  class Twin
    extend Representer # include ::representer for transformator caching.

    extend Uber::InheritableAttr
    inheritable_attr :representer_class
    self.representer_class = Class.new(Decorator::Hash)

    # DISCUSS: since i started playing with Representable::Object, which is way faster than
    # going the Hash way, i use two schema representers here. they are identical except for
    # the engine.
    # it would be cool to have only one, one day.
    inheritable_attr :object_representer_class
    self.object_representer_class = Class.new(Decorator::Object)

    def self.feature(*)
      puts "FIXME"
    end

    # TODO: move to Declarative, as in Representable and Reform.
    def self.property(name, options={}, &block)
      deprecate_as!(options) # TODO: remove me in 0.1.0
      options[:private_name] = options.delete(:from) || name
      options[:pass_options] = true

      representer_class.property(name, options, &block).tap do |definition|
        mod = Module.new do
          define_method(name)       { read_property(name, options[:private_name]) }
          define_method("#{name}=") { |value| write_property(name, options[:private_name], value, definition) } # TODO: this is more like prototyping.
        end
        include mod
      end

      # FIXME: use only one representer.
      object_representer_class.property(name, options, &block).tap do |definition|
        mod = Module.new do
          define_method(name)       { read_property(name, options[:private_name]) }
          define_method("#{name}=") { |value| write_property(name, options[:private_name], value, definition) } # TODO: this is more like prototyping.
        end
        include mod

        # TODO: temporary hack to make definition not look typed. maybe we should make :twin copy of :extend and then get everything accepting :extend?
        definition.merge!(:twin => definition[:extend].evaluate(nil)) if definition[:extend]
        definition.delete!(:extend)
      end
    end

    def self.collection(name, options={}, &block)
      property(name, options.merge(:collection => true), &block)<commit_msg>make hash representer simpler.<commit_after>require 'uber/inheritable_attr'
require 'disposable/twin/representer'
require 'disposable/twin/option'
require 'disposable/twin/builder'

# Twin.new(model/composition hash/hash, options)
#   assign hash to @fields
#   write: write to @fields
#   sync/save is the only way to write back to the model.

module Disposable
  class Twin
    extend Representer # include ::representer for transformator caching.

    extend Uber::InheritableAttr
    inheritable_attr :representer_class
    self.representer_class = Class.new(Decorator::Hash)

    # DISCUSS: since i started playing with Representable::Object, which is way faster than
    # going the Hash way, i use two schema representers here. they are identical except for
    # the engine.
    # it would be cool to have only one, one day.
    inheritable_attr :object_representer_class
    self.object_representer_class = Class.new(Decorator::Object)

    def self.feature(*)
      puts "FIXME"
    end

    # TODO: move to Declarative, as in Representable and Reform.
    def self.property(name, options={}, &block)
      deprecate_as!(options) # TODO: remove me in 0.1.0
      options[:private_name] = options.delete(:from) || name
      options[:pass_options] = true

      representer_class.property(name, options, &block)

      # FIXME: use only one representer. and make object_representer the authorative one, we really need the hash one only once.
      object_representer_class.property(name, options, &block).tap do |definition|
        mod = Module.new do
          define_method(name)       { read_property(name, options[:private_name]) }
          define_method("#{name}=") { |value| write_property(name, options[:private_name], value, definition) } # TODO: this is more like prototyping.
        end
        include mod

        # TODO: temporary hack to make definition not look typed. maybe we should make :twin copy of :extend and then get everything accepting :extend?
        definition.merge!(:twin => definition[:extend].evaluate(nil)) if definition[:extend]
        definition.delete!(:extend)
      end
    end

    def self.collection(name, options={}, &block)
      property(name, options.merge(:collection => true), &block)
{'fraction_non_alphanumeric': 0.09749362786745965, 'fraction_numerical': 0.001274426508071368, 'mean_word_length': 3.540983606557377, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1965139', 'n_tokens_mistral': 1365, 'n_tokens_neox': 1301, 'n_words': 422}