Class: Types::Struct
- Defined in:
- lib/solidity/typed/struct.rb,
lib/solidity/typed/struct_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
-
.build_class(class_name, scope: Types, **attributes) ⇒ Object
(also: new)
todo/fix: scope: keep empty by default.
- .zero ⇒ Object
Instance Method Summary collapse
- #==(other) ⇒ Object
- #as_data ⇒ Object
-
#initialize(*args, **kwargs) ⇒ Struct
constructor
A new instance of Struct.
- #zero? ⇒ Boolean
Methods inherited from Typed
#as_json, dump, serialize, #serialize, #type, type
Constructor Details
#initialize(*args, **kwargs) ⇒ Struct
Returns a new instance of Struct.
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 |
# File 'lib/solidity/typed/struct.rb', line 18 def initialize( *args, **kwargs ) ## fix-fix-fix: first check for matching args - why? why not? if kwargs.size > 0 ## assume kwargs init self.class.attributes.each do |key, type| ## note: allow unused keys (will get set to zero) value = kwargs.has_key?( key ) ? kwargs[ key ] : type.new_zero value = if value.is_a?( Typed ) ## fix-fix-fix - check type match here!!! value else type.new( value ) end instance_variable_set( "@#{key}", value ) end else self.class.attributes.zip( args ).each do |(key, type), value| value = if value.is_a?(Typed) ## fix-fix-fix - check type match here!!! value else type.new( value ) end instance_variable_set( "@#{key}", value ) end end self ## note: return reference to self for chaining method calls end |
Class Method Details
.build_class(class_name, scope: Types, **attributes) ⇒ Object Also known as: new
todo/fix: scope: keep empty by default
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 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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/solidity/typed/struct_builder.rb', line 8 def self.build_class( class_name, scope: Types, **attributes ) ## todo/fix: ## add self.class.type class method ## returns TypedStruct<> instance with typedef info ## ## add name & format ## e.g. :struct (why? why not? or :tuple? if using abi names?) ## tuple( types,... ) - flattend (recursive)!!! - why? why not? ## todo/fix: ## check if valid class_name MUST start with uppercase letter etc. ## todo/fix: check if constant is undefined in scoped namespace!!!! ## map type symbols (:uint, :address, etc.) ## to type for now "by hand" here attributes = attributes.map do |key,type| ## t =type ## t = t.type if t.is_a?( Class ) && t.ancestors.include?( Typed ) [key, typeof( type )] end.to_h klass = Class.new( Struct ) do attributes.each do |key,type| define_method( key ) do instance_variable_get( "@#{key}" ) end ## note: for Bool auto-add getter with question mark (e.g. voted? etc.) ## why? why not? if type == BoolType.instance define_method( "#{key}?" ) do instance_variable_get( "@#{key}" ) end end define_method( "#{key}=" ) do |value| ## todo/fix: ## check if arg is typed && type match? ## if not (assume literal) try to convert to type!!!! value = if value.is_a?(Typed) ## fix-fix-fix - check type match here!!! value else type.new( value ) end instance_variable_set( "@#{key}", value ) end end alias_method :old_freeze, :freeze # note: store "old" orginal version of freeze define_method( :freeze ) do old_freeze ## same as calling super attributes.keys.each do |key| instance_variable_get( "@#{key}" ).freeze end self # return reference to self end end type = StructType.new( class_name, klass ) klass.define_singleton_method( :type ) do @type ||= type end ## add attributes (with keys / types) class method klass.define_singleton_method( :attributes ) do attributes end ## add self.new too - note: call/forward to "old" orginal self.new of Event (base) class klass.define_singleton_method( :new ) do |*args, **kwargs| if kwargs.size > 0 ## assume kwargs ## -fix-fix-fix- check all keywords if part or struct here too!!! old_new( **kwargs ) else if args.empty? ## no args - use new_zero and set (initialize) all ivars to zero new_zero else if args.size != attributes.size ## check for required args/params - all MUST be passed in!!! raise ArgumentError, "[Struct] wrong number of arguments for #{name}.new - #{args.size} for #{attributes.size}" end old_new( *args ) end end end klass.define_singleton_method( :new_zero ) do values = attributes.values.map do |type| if type.respond_to?( :new_zero ) type.new_zero else raise ArgumentError, "[Struct] no new_zero support for type #{type}; sorry" end end old_new( *values ) end =begin ## note: use Kernel for "namespacing" ## make all enums convenience converters (always) global ## including uppercase methods (e.g. State(), Color(), etc.) does NOT work otherwise (with other module includes) ## add global "Kernel" convenience converter function ## e.g. Vote(0) is same as Vote.convert(0) Kernel.class_eval( <<RUBY ) def #{class_name}( arg ) #{class_name}.convert( arg ) end RUBY =end ## note: use scoped (module) and NOT Object for namespacing ## use include Safe to make all structs global ## fix-fix-fix - make class_name unique across contracts (e.g. reuse same name in different contract) scope.const_set( class_name, klass ) ## returns klass (plus sets global constant class name) end |
.zero ⇒ Object
5 6 7 8 9 10 11 12 |
# File 'lib/solidity/typed/struct.rb', line 5 def self.zero ## note: freeze return new zero (for "singelton" & "immutable" zero instance) ## todo/fix: ## in build_class add freeze for composite/reference objects ## that is, arrays, hash mappings, structs etc. ## freeze only works for now for "value" objects e.g. integer, bool, etc. @zero ||= new_zero.freeze end |
Instance Method Details
#==(other) ⇒ Object
58 59 60 61 62 63 64 65 66 |
# File 'lib/solidity/typed/struct.rb', line 58 def ==(other) if other.is_a?( self.class ) self.class.attributes.keys.all? do |key| __send__( key ) == other.__send__( key ) end else false end end |
#as_data ⇒ Object
47 48 49 50 51 52 53 54 |
# File 'lib/solidity/typed/struct.rb', line 47 def as_data self.class.attributes.keys.map do |key| ivar = instance_variable_get( "@#{key}" ) puts " @#{key}:" pp ivar ivar.as_data end end |
#zero? ⇒ Boolean
14 |
# File 'lib/solidity/typed/struct.rb', line 14 def zero?() self == self.class.zero; end |