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, #unwrap, #val, #~

Constructor Details

#initialize(hash = {}) ⇒ Property

Returns a new instance of Property.



436
437
438
# File 'lib/primitive_wrapper.rb', line 436

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



496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
# File 'lib/primitive_wrapper.rb', line 496

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)


440
441
442
443
# File 'lib/primitive_wrapper.rb', line 440

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

.good_candidate_name?(name) ⇒ Boolean

Returns:

  • (Boolean)


445
446
447
448
449
450
451
# File 'lib/primitive_wrapper.rb', line 445

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)


453
454
455
456
457
458
# File 'lib/primitive_wrapper.rb', line 453

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



460
461
462
463
464
465
466
467
468
469
470
471
# File 'lib/primitive_wrapper.rb', line 460

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



545
546
547
# File 'lib/primitive_wrapper.rb', line 545

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

#[]=(idx, val) ⇒ Object



549
550
551
552
553
554
555
556
557
558
559
# File 'lib/primitive_wrapper.rb', line 549

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)


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

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

#deferred_properties!Object



577
578
579
580
# File 'lib/primitive_wrapper.rb', line 577

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

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



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

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



573
574
575
576
# File 'lib/primitive_wrapper.rb', line 573

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

#import_hash!(hash) ⇒ Object



561
562
563
564
565
# File 'lib/primitive_wrapper.rb', line 561

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

#property?(tst) ⇒ Boolean

Returns:

  • (Boolean)


582
583
584
585
586
587
# File 'lib/primitive_wrapper.rb', line 582

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

#rekey!Object



483
484
485
486
487
488
489
490
491
492
493
494
# File 'lib/primitive_wrapper.rb', line 483

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



533
534
535
536
537
538
539
540
541
542
543
# File 'lib/primitive_wrapper.rb', line 533

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



476
477
478
479
480
481
# File 'lib/primitive_wrapper.rb', line 476

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

#valid_type(prm) ⇒ Object



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

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