Class: Types::Array

Inherits:
TypedReference show all
Extended by:
Forwardable
Defined in:
lib/solidity/typed/array.rb,
lib/solidity/typed/array_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

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from TypedReference

#==, #eql?, #hash

Methods inherited from Typed

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

Constructor Details

#initialize(initial_value = []) ⇒ Array

Returns a new instance of Array.

Raises:

  • (ArgumentError)


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/solidity/typed/array.rb', line 22

def initialize( initial_value = [] )
    ## was: initial_value ||= []
    ##     check if nil gets passed in - default not used?  
    raise ArgumentError, "expected literal of type #{type}; got typed #{initial_value.pretty_print_inspect}"    if initial_value.is_a?( Typed )    
 
   @data =  type.check_and_normalize_literal( initial_value ).map do |item|
                  type.sub_type.new( item )
            end 

    ## check size if fixed (must all set to zero up to size!!!)         
    if type.size > 0  ## auto-init with zeros
       if @data.size >= type.size  ## note: allow ("fixed") array to grow bigger for now - why? why not?
          # bingo! already setup with inital values
       else
          self.size = type.size
       end
    end     
end

Class Method Details

.build_class(sub_type, size = 0) ⇒ Object Also known as: new

note: add size option here (size=0) default is dynamic (not fixed)!!!



6
7
8
9
10
11
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
# File 'lib/solidity/typed/array_builder.rb', line 6

def self.build_class( sub_type, size=0 )
  ## add convenience sub_type helper here - why? why not?
  ## sub_type = Type.create( sub_type )  if sub_type.is_a?( Symbol ) ||
  ##                                       sub_type.is_a?( String )
  ## sub_type = sub_type.type   if sub_type.is_a?( Class ) && sub_type.ancestors.include?( Typed )
   sub_type = typeof( sub_type )    
  
  type = ArrayType.instance( sub_type, size )

  class_name =  type.typedclass_name
  
    ## note: keep a class cache
    ##  note: klasses may have different init sizes (default 0)
    cache           = @@cache ||= {}
    klass           = cache[ class_name ]
    ## fix-fix-fix - check if const klass defined for cache (no cache needed)!!!!!!!!
  
    if klass.nil?
      klass = Class.new( Array )
      klass.define_singleton_method( :type ) do
        @type  ||= type
      end

      ## add self.new too - note: call/forward to "old" orginal self.new of Event (base) class
      klass.define_singleton_method( :new ) do |*args|
         old_new( *args )
      end
    
      ## add to cache for later (re)use
      cache[ class_name ] = klass

      ## for default scope use Kernel - why? why not?
      ##   or Globals  or Typed - why? why not?
      Types.const_set( class_name, klass )
    end

    klass
end

.zeroObject

todo/check: make “internal” data (array) available? why? why not? attr_reader :data



9
# File 'lib/solidity/typed/array.rb', line 9

def self.zero()  @zero ||= new; end

Instance Method Details

#[](index) ⇒ Object

Raises:

  • (ArgumentError)


51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/solidity/typed/array.rb', line 51

def []( index )
  ## use serialize to get value (why not value) - why? why not?
  index = index.is_a?( Typed ) ? index.as_data : index

  ## fix: use index out of bounds error - why? why not?
  raise ArgumentError, "Index out of bounds -  #{index} : #{index.class.name} >= #{@data.size}"   if index >= @data.size

  obj = @data[ index ] 
  if obj.nil?  
    obj = type.sub_type.new_zero
    @data[ index ] = obj
  end
  obj
end

#[]=(index, new_value) ⇒ Object

Raises:

  • (ArgumentError)


66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/solidity/typed/array.rb', line 66

def []=(index, new_value) 
   ## use serialize to get value (why not value) - why? why not?
   index = index.is_a?( Typed ) ? index.as_data : index
 
   raise ArgumentError, "Sparse arrays are not supported; index out of bounds - sorry"   if index >= @data.size

   # fix-fix-fix: allow typed value here (not only literals)!!!
   obj = if new_value.is_a?( Typed ) 
             new_value
         else
             type.sub_type.new( new_value )
         end

   @data[ index ] = obj
end

#as_dataObject



157
158
159
# File 'lib/solidity/typed/array.rb', line 157

def as_data
   @data.map {|item| item.as_data } 
end

#clearObject



148
149
150
151
152
153
154
# File 'lib/solidity/typed/array.rb', line 148

def clear
  ## note: reset ary to zero  (NOT empty e.g. [])
  ##         differes for "fixed" size arrays
  @data.clear
  self.size = type.size   if type.size > 0  ## auto-init with zeros
  self  # return reference to self
end

#delete(index) ⇒ Object

Raises:

  • (ArgumentError)


109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/solidity/typed/array.rb', line 109

def delete( index )
  ## note sets the element to zero!!!
  ##  will NOT remove from array itself!!!

  ## use serialize to get value (why not value) - why? why not?
  index = index.is_a?( Typed ) ? index.as_data : index

  ## fix: use index out of bounds error - why? why not?
  raise ArgumentError, "Index out of bounds -  #{index} : #{index.class.name} >= #{@data.size}"   if index >= @data.size

  @data[ index ] = type.sub_type.new_zero
  self
end

#popObject



83
84
85
86
87
88
89
90
# File 'lib/solidity/typed/array.rb', line 83

def pop
   ## note: pop will decrease size/lenght!!!
   ## will remove LAST item in array!!!
   ##
   ## Pop is used to delete or remove an element 
   ##   in a dynamic array from the end.
   @data.pop
end

#pretty_print(printer) ⇒ Object



161
162
163
# File 'lib/solidity/typed/array.rb', line 161

def pretty_print( printer ) 
  printer.text( "<ref #{type}:#{@data.pretty_print_inspect}>" ); 
end

#push(new_value) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/solidity/typed/array.rb', line 92

def push( new_value )
   ## note: push will increase size/length!!!
   ##
   ## Push is used to add new element to a dynamic array,
   ##  when you push a value to an array, it becomes the last value
   obj = if new_value.is_a?( Typed ) 
             new_value
         else
             type.sub_type.new( new_value )
         end
   @data.push( obj )

   ## note: returns array.size (NOT array itself!!!) to keep compatible with solidity - why? why not?
   @data.size
end

#size=(new_size) ⇒ Object Also known as: length=



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/solidity/typed/array.rb', line 124

def size=( new_size )
  ## todo/check: value must be greater 0 and greater than current size
  diff = new_size - @data.size
  if diff == 0
    ## stay as is; do nothing
  elsif diff > 0
    ## todo/check:
    ##    always return (deep) frozen zero object - why? why not?
    ##     let user change the returned zero object - why? why not?
    if type.sub_type.respond_to?( :new_zero )
      ## note: use a new unfrozen copy of the zero object
      ##    changes to the object MUST be possible (new "empty" modifable object expected)
      diff.times { @data << type.sub_type.new_zero }
    else
       raise "[Array]#length= cannot create new_zero for type #{type.sub_type} - sorry"
    end
  else  ## diff < 0
    ## fix-fix-fix - raise error here - cannot shrink/delete via length!!!
  end
  self  # return reference to self
end

#zero?Boolean

Returns:

  • (Boolean)


10
11
12
13
14
15
16
17
18
# File 'lib/solidity/typed/array.rb', line 10

def zero?()
    if type.size == 0 ## assume dynamic (starts with empty array)
      @data.empty?
    else   ## assume fixed size array (initialized with x zero items) 
      ## use zero to check - why? why not?
      ## fix-fix-fix  - add support for fixed Array here or use a new class - why? why not?
      self == self.class.zero
    end   
end