Class: Types::Enum

Inherits:
Typed
  • Object
show all
Defined in:
lib/solidity/typed/enum.rb,
lib/solidity/typed/enum_builder.rb

Constant Summary

Constants inherited from Typed

Typed::ADDRESS_ZERO, Typed::BYTES20_ZERO, Typed::BYTES32_ZERO, Typed::BYTES_ZERO, Typed::INSCRIPTION_ID_ZERO, Typed::STRING_ZERO

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Typed

#as_json, dump, serialize, #serialize, #type, type

Constructor Details

#initialize(key, value) ⇒ Enum

Returns a new instance of Enum.



31
32
33
34
35
36
# File 'lib/solidity/typed/enum.rb', line 31

def initialize( key, value )
  @key   = key
  @value = value
  self.freeze   ## make "immutable"
  self
end

Instance Attribute Details

#keyObject (readonly)

return a new Enum read-only class



27
28
29
# File 'lib/solidity/typed/enum.rb', line 27

def key
  @key
end

#valueObject (readonly)

Returns the value of attribute value.



28
29
30
# File 'lib/solidity/typed/enum.rb', line 28

def value
  @value
end

Class Method Details

._typecheck_enum!(o) ⇒ Object



38
39
40
41
42
43
44
# File 'lib/solidity/typed/enum.rb', line 38

def self._typecheck_enum!( o )
  if o.instance_of?( self )
    o
  else
    raise TypeError.new( "[enum] enum >#{name}< type expected; got >#{o.class.inspect}<" )
  end
end

.build_class(class_name, *args, scope: Types) ⇒ Object Also known as: new



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/solidity/typed/enum_builder.rb', line 12

def self.build_class( class_name, *args, scope: Types )
  if args.size > 0
    ## e.g. :Color, :red, :green, :blue
    ##         or
    ##      :Color, [:red, :green, :blue]
    ##   note: start counting a zero (0) !!!
    keys   = args
    values = (0...keys.size).to_a   # note: use ... (exclusive) range
    e = Hash[ keys.zip( values ) ]
  else
     raise ArgumentError, "[enum] no members declared - min. one member required; got #{args}; sorry"
  end

  ## todo/fix:
  ##  check class name MUST start with uppercase letter

  ## check if all keys are symbols and follow the ruby id(entifier) naming rules
  ##   todo/check - allow uppercase fist A-Z letters - why? why not?
  e.keys.each do |key|
    if key.is_a?( Symbol ) && key =~ /\A[a-z][a-zA-Z0-9_]*\z/
    else
      raise ArgumentError.new( "[enum] members to enum must be all symbols following the ruby/solidity id naming rules; >#{key}< failed" )
    end
  end

  klass = Class.new( Enum )

 
  ## add self.new too - note: call/forward to "old" orginal self.new of Event (base) class
  klass.define_singleton_method( :new ) do |*new_args|
      raise ArgumentError, "enum #{klass.name} - do NOT call new EVER; reuse existing enum members! sorry"
  end
  ## make new - private too - why? why not?


  e.each do |key,value|
    klass.class_eval( <<RUBY )
      #{key.upcase} = old_new( :#{key}, #{value} )

      def #{key}?
        self == #{key.upcase}
      end

      def self.#{key}
        #{key.upcase}
      end
RUBY
  end

  klass.class_eval( <<RUBY )
    def self.members
      @members ||= [#{e.keys.map {|key|key.upcase}.join(',')}].freeze
    end
RUBY


  type = EnumType.new( class_name, klass )
  klass.define_singleton_method( :type ) do
    @type ||= type       
  end

=begin
  ## note: use Kernel for "namespacing"
  ##   make all enums Kernel convenience converters (always) global
  ##     including uppercase methods (e.g. State(), Color(), etc.) does NOT work otherwise (with other module includes)

  ## add global convenience converter function
  ##  e.g. State(0) is same as State.convert(0)
  ##       Color(0) is same as Color.convert(0)
  Kernel.class_eval( <<RUBY )
    def #{class_name}( arg )
       #{class_name}.convert( arg )
    end
RUBY
=end
  ## note: use scoped(class) and NO Object for namespacing
  scope.const_set( class_name, klass )   ## returns klass (plus sets global constant class name)
  klass
end

.convert(arg) ⇒ Object



95
96
97
98
99
100
101
# File 'lib/solidity/typed/enum.rb', line 95

def self.convert( arg )
  ## todo/check: support keys too - why? why not?
  ## e.g. Color(0), Color(1)
  ##      Color(:red), Color(:blue) - why? why not?
  ## note: will ALWAYS look-up by (member) index and NOT by value (integer number value might be different!!)
  members[ arg ]
end

.key(key) ⇒ Object Also known as: []



64
65
66
67
68
69
# File 'lib/solidity/typed/enum.rb', line 64

def self.key( key )
  ## note: returns nil now for unknown keys
  ##   use/raise IndexError or something - why? why not?
  @hash_by_key ||= Hash[ keys.zip( members ) ].freeze
  @hash_by_key[key]
end

.keysObject



59
60
61
62
# File 'lib/solidity/typed/enum.rb', line 59

def self.keys
  @keys ||= members.map {|member| member.key}.freeze
  @keys
end

.maxObject



88
# File 'lib/solidity/typed/enum.rb', line 88

def self.max()  members[-1]; end

.minObject



87
# File 'lib/solidity/typed/enum.rb', line 87

def self.min()  members[0]; end

.sizeObject Also known as: length



90
# File 'lib/solidity/typed/enum.rb', line 90

def self.size() keys.size; end

.value(value) ⇒ Object



80
81
82
83
84
85
# File 'lib/solidity/typed/enum.rb', line 80

def self.value( value )
  ## note: returns nil now for unknown values
  ##   use/raise IndexError or something - why? why not?
  @hash_by_value ||= Hash[ values.zip( members ) ].freeze
  @hash_by_value[value]
end

.valuesObject



75
76
77
78
# File 'lib/solidity/typed/enum.rb', line 75

def self.values
  @values ||= members.map {|member| member.value}.freeze
  @values
end

.zeroObject



22
# File 'lib/solidity/typed/enum.rb', line 22

def self.zero() members[0]; end

Instance Method Details

#==(other) ⇒ Object



48
49
50
51
52
53
54
# File 'lib/solidity/typed/enum.rb', line 48

def ==( other )
  if other.is_a?( Integer ) && other == 0   ## note: only allow compare by zero (0) integer - why? why not?
    @value == 0
  else
    @value == _typecheck_enum!( other ).value
  end
end

#_typecheck_enum!(o) ⇒ Object



45
# File 'lib/solidity/typed/enum.rb', line 45

def _typecheck_enum!( o ) self.class._typecheck_enum!( o ); end

#as_dataObject

add to_b/to_bool support (see safebool @ github.com/s6ruby/safebool) - why? why not?

def parse_bool() @value != 0; end ## nonzero == true, zero == false like numbers



110
# File 'lib/solidity/typed/enum.rb', line 110

def as_data() @value; end

#pretty_print(printer) ⇒ Object



112
113
114
# File 'lib/solidity/typed/enum.rb', line 112

def pretty_print( printer ) 
  printer.text( "<val #{type}:#{@key}(#{@value})>" ); 
end

#to_iObject

add to_i, to_int - why? why not?



104
# File 'lib/solidity/typed/enum.rb', line 104

def to_i()       @value; end

#to_intObject

allows Integer( .. )



105
# File 'lib/solidity/typed/enum.rb', line 105

def to_int()     @value; end

#zero?Boolean

note: use compare by identity (object_id) and NOT value e.g. 0

Returns:

  • (Boolean)


23
# File 'lib/solidity/typed/enum.rb', line 23

def zero?() self == self.class.zero; end