Class: Property

Inherits:
Value show all
Defined in:
lib/primitive_wrapper.rb

Constant Summary collapse

GOOD_KEY_RGX =
/\A[a-zA-Z_][a-zA-Z_0-9]*\z/

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Value

#!=, #==, #ensure_valid, #freeze, freeze_raise?, ignore_on_freeze, #inspect, #prim_value, raise_on_freeze, #replace, #to_s, #to_wrapper, #type, #type_of?, #unwrap, #val, #wrapped?, #~

Constructor Details

#initialize(hash = {}) ⇒ Property

Returns a new instance of Property.



548
549
550
# File 'lib/primitive_wrapper.rb', line 548

def initialize(hash={})
  self.val=(hash)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object



608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
# File 'lib/primitive_wrapper.rb', line 608

def method_missing(method, *args, &block)
  flag_good = @good_keys.include? method
  unless flag_good
    unless method[-1]=='='
      if @value.include? method
        rekey!
        flag_good = @good_keys.include? method
      end
    end
  end
  raise "Illegal Block attachment" unless block.nil?
  if flag_good
    raise "*** ArgumentError Exception: wrong number of arguments (given #{args.count}, expected 0)" unless args.empty?
    return @value[method]  
  end
  if method[-1]=='='  # assignment
    key = method[0..-2].to_sym      
    if args.count==1
      if @good_keys.include? key
        @value[key] = args[0]
        return true
      end
      # creating a new key here ... good or bad?
      if self.class.good_key? key
        @good_keys[key]=true
      else
        @hold_keys[key]=true
      end
      return @value[key] = args[0] 
    end
    raise "*** ArgumentError Exception: wrong number of arguments (given #{args.count}, expected 1)"
  else
    # lookup failed ... punt
    super
  end
end

Class Method Details

.bad_key?(idx) ⇒ Boolean

Returns:

  • (Boolean)


552
553
554
555
# File 'lib/primitive_wrapper.rb', line 552

def self.bad_key?(idx)
  @badkeys ||= {}
  true==@badkeys[idx]
end

.good_candidate_name?(name) ⇒ Boolean

Returns:

  • (Boolean)


557
558
559
560
561
562
563
# File 'lib/primitive_wrapper.rb', line 557

def self.good_candidate_name? name
  name = name.prim_value
  return false unless name.kind_of? Symbol
  tst = GOOD_KEY_RGX.match name
  return false if tst.nil?
  true
end

.good_key?(idx) ⇒ Boolean

syntax and not bad … does not check to see if taken as only instansts can do that

Returns:

  • (Boolean)


565
566
567
568
569
570
# File 'lib/primitive_wrapper.rb', line 565

def self.good_key?(idx)  # syntax and not bad ... does not check to see if taken as only instansts can do that
  idx = idx.prim_value
  return false unless good_candidate_name? idx 
  return false if bad_key?(idx)
  true    
end

.reserve_property_names!(*names) ⇒ Object



572
573
574
575
576
577
578
579
580
581
582
583
# File 'lib/primitive_wrapper.rb', line 572

def self.reserve_property_names!(*names)
  @badkeys ||= {}
  names = names.first if names.first.kind_of? Array
  names.each do |key|
    next if key[-1]=='!'
    next if key[-1]=='?'
    kw = key[-1]=='=' ? key[0..-2] : key[0..-1]
    md = GOOD_KEY_RGX.match kw
    next if md.nil?  # bad key 
    @badkeys[key]=true
  end
end

Instance Method Details

#[](idx) ⇒ Object



657
658
659
# File 'lib/primitive_wrapper.rb', line 657

def [](idx)
  @value[idx]
end

#[]=(idx, val) ⇒ Object



661
662
663
664
665
666
667
668
669
670
671
# File 'lib/primitive_wrapper.rb', line 661

def []=(idx,val)
  idx = idx.prim_value # in case it is wrapped
  rtn = @value[idx] = val
  # now put key in one of two bins
  if self.class.good_key? idx
    @good_keys[idx]=true
  else
    @hold_keys[idx]=true
  end
  return rtn
end

#deferred?(tst) ⇒ Boolean

Returns:

  • (Boolean)


701
702
703
704
705
706
# File 'lib/primitive_wrapper.rb', line 701

def deferred?(tst)
  rekey!
  tst = tst.prim_value
  return true if @hold_keys.include? tst
  false
end

#deferred_properties!Object



689
690
691
692
# File 'lib/primitive_wrapper.rb', line 689

def deferred_properties!
  rekey!
  @hold_keys.keys  # can't sort bad keys without a ton of work
end

#define_properties!(ary, dflt = "") ⇒ Object



708
709
710
711
712
713
714
715
716
717
718
# File 'lib/primitive_wrapper.rb', line 708

def define_properties!(ary, dflt="")
  ary.each do |item|
    key = item.prim_value
    raise "*** Property Error: must use Symbol type to define properties" unless key.kind_of? Symbol
    raise "*** Property Error: property #{key.inspect} already defined" if @good_keys.include? key
    raise "*** Property Error: property #{key.inspect} violates naming convention" unless self.class.good_candidate_name? key
    raise "*** Property Error: property #{key.inspect} is reserved" if self.class.bad_key? key
    @good_keys[key]=true
    @value[key]=dflt
  end
end

#defined_properties!Object



685
686
687
688
# File 'lib/primitive_wrapper.rb', line 685

def defined_properties!
  rekey!
  @good_keys.keys.sort
end

#import_hash!(hash) ⇒ Object



673
674
675
676
677
# File 'lib/primitive_wrapper.rb', line 673

def import_hash!(hash)
  hash.each_pair do |key,val|
    self[key]=val
  end 
end

#property?(tst) ⇒ Boolean

Returns:

  • (Boolean)


694
695
696
697
698
699
# File 'lib/primitive_wrapper.rb', line 694

def property?(tst)
  rekey!
  tst = tst.prim_value
  return true if @good_keys.include? tst
  false
end

#rekey!Object



595
596
597
598
599
600
601
602
603
604
605
606
# File 'lib/primitive_wrapper.rb', line 595

def rekey!
  @good_keys = {}  # these keys can be properties
  @hold_keys  = {} # these keys can't
  @value.each_pair do |pkey,val|
    key = pkey.prim_value
    if self.class.good_key? key
      @good_keys[key.prim_value]=true
    else
      @hold_keys[key.prim_value]=true
    end
  end
end

#split!Object



645
646
647
648
649
650
651
652
653
654
655
# File 'lib/primitive_wrapper.rb', line 645

def split!
  good = {}
  bad = {}
  @good_keys.each_pair do |key,val|    
    good[key] = @value[key]
  end
  @hold_keys.each_pair do |key,val|
    bad[key] = @value[key]
  end
  return [good, bad]
end

#val=(hash) ⇒ Object

assign replacement hash



588
589
590
591
592
593
# File 'lib/primitive_wrapper.rb', line 588

def val=(hash)
  ensure_valid(hash)
  hash = hash.prim_value
  @value = hash    # keep this as prime as possible
  rekey!
end

#valid_type(prm) ⇒ Object



679
680
681
682
683
# File 'lib/primitive_wrapper.rb', line 679

def valid_type(prm)
  return true if prm.kind_of? Hash
  return true if prm.kind_of? Property
  false
end