Class: Twostroke::Runtime::Types::Object

Inherits:
Value
  • Object
show all
Defined in:
lib/twostroke/runtime/types/object.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Value

#has_instance

Constructor Details

#initializeObject

Returns a new instance of Object.



6
7
8
9
10
11
12
13
14
# File 'lib/twostroke/runtime/types/object.rb', line 6

def initialize
  @extensible = true
  @properties = {}
  @accessors = {}
  @prototype ||= defined?(@@_prototype) ? @@_prototype : Null.new
  @_class = self.class.constructor_function if !defined?(@_class) && self.class.respond_to?(:constructor_function)
  @data = {} # for abitrary data not safe to store as a property
  proto_put "constructor", @_class
end

Instance Attribute Details

#_classObject

Returns the value of attribute _class.



3
4
5
# File 'lib/twostroke/runtime/types/object.rb', line 3

def _class
  @_class
end

#accessorsObject (readonly)

Returns the value of attribute accessors.



4
5
6
# File 'lib/twostroke/runtime/types/object.rb', line 4

def accessors
  @accessors
end

#dataObject (readonly)

Returns the value of attribute data.



4
5
6
# File 'lib/twostroke/runtime/types/object.rb', line 4

def data
  @data
end

#extensibleObject (readonly)

Returns the value of attribute extensible.



4
5
6
# File 'lib/twostroke/runtime/types/object.rb', line 4

def extensible
  @extensible
end

#propertiesObject (readonly)

Returns the value of attribute properties.



4
5
6
# File 'lib/twostroke/runtime/types/object.rb', line 4

def properties
  @properties
end

#prototypeObject

Returns the value of attribute prototype.



3
4
5
# File 'lib/twostroke/runtime/types/object.rb', line 3

def prototype
  @prototype
end

Class Method Details

.set_global_prototype(proto) ⇒ Object



24
25
26
# File 'lib/twostroke/runtime/types/object.rb', line 24

def self.set_global_prototype(proto)
  @@_prototype = proto
end

Instance Method Details

#can_put(prop) ⇒ Object



102
103
104
# File 'lib/twostroke/runtime/types/object.rb', line 102

def can_put(prop)
  extensible && (!accessors.has_key?(prop) || accessors[prop][:configurable])
end

#construct(opts = {}) ⇒ Object



46
47
48
49
50
51
# File 'lib/twostroke/runtime/types/object.rb', line 46

def construct(opts = {})
  @constructing = true
  opts.each { |k,v| send "#{k}=", v }
  yield if block_given?
  @constructing = false
end

#constructing?Boolean

Returns:



32
33
34
# File 'lib/twostroke/runtime/types/object.rb', line 32

def constructing?
  @constructing
end

#default_value(hint = nil) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/twostroke/runtime/types/object.rb', line 134

def default_value(hint = nil)      
  if hint.nil?
    # @TODO
    # hint = is_a?(Date) ? "String" : "Number"
    hint = "Number"
  end
  
  if hint == "String"
    toString = get "toString"
    if toString.respond_to? :call
      str = toString.call(nil, self, [])
      return str if str.is_a? Primitive
    end
    valueOf = get "valueOf"
    if valueOf.respond_to? :call
      val = valueOf.call(nil, self, [])
      return val if val.is_a? Primitive
    end
    Twostroke::Runtime::Lib.throw_type_error "could not convert object to string"
  elsif hint == "Number"
    valueOf = get "valueOf"
    if valueOf.respond_to? :call
      val = valueOf.call(nil, self, [])
      return val if val.is_a? Primitive
    end
    toString = get "toString"
    if toString.respond_to? :call
      str = toString.call(nil, self, [])
      return str if str.is_a? Primitive
    end
    Twostroke::Runtime::Lib.throw_type_error "could not convert object to string"
  end
end

#define_own_property(prop, descriptor) ⇒ Object



168
169
170
171
172
173
174
175
176
177
# File 'lib/twostroke/runtime/types/object.rb', line 168

def define_own_property(prop, descriptor)
  unless descriptor.has_key?(:get) || descriptor.has_key?(:set)
    descriptor[:get] = ->(this) { descriptor[:value] }
    descriptor[:set] = ->(this, value) { descriptor[:value] = value }
    descriptor[:value] ||= Undefined.new
  else
    descriptor[:writable] = true if descriptor.has_key?(:set)
  end
  accessors[prop] = descriptor
end

#delete(prop) ⇒ Object



118
119
120
121
122
123
124
# File 'lib/twostroke/runtime/types/object.rb', line 118

def delete(prop)
  if accessors.has_key? prop
    accessors.delete prop if accessors[prop][:configurable]
  elsif prop != "prototype"
    properties.delete prop
  end
end

#delete!(prop) ⇒ Object



126
127
128
129
130
131
132
# File 'lib/twostroke/runtime/types/object.rb', line 126

def delete!(prop)
  if accessors.has_key? prop
    accessors.delete prop if accessors[prop][:configurable]
  else
    properties.delete prop
  end
end

#each_enumerable_property(&bk) ⇒ Object



77
78
79
80
81
82
83
# File 'lib/twostroke/runtime/types/object.rb', line 77

def each_enumerable_property(&bk)
  accessors.select { |k,v| v[:enumerable] }.each { |k,v| yield k }
  properties.reject { |k,v| accessors[k] }.each { |k,v| yield k }
  if prototype && prototype.is_a?(Object)
    prototype.each_enumerable_property &bk
  end
end

#generic_itemsObject

this allows us to treat the object like a generic array. the value of this method is not memoized, so call sparingly



38
39
40
41
42
43
44
# File 'lib/twostroke/runtime/types/object.rb', line 38

def generic_items
  return items if respond_to? :items
  len = Twostroke::Runtime::Types.to_number(get "length").number
  return [] if (len.is_a?(Float) && (len.nan? || len.infinite?)) || len < 0
  len = len.to_i
  (0...len).map { |i| get i.to_s }
end

#get(prop, this = self) ⇒ Object



53
54
55
56
57
58
59
60
61
# File 'lib/twostroke/runtime/types/object.rb', line 53

def get(prop, this = self)
  if accessors.has_key? prop
    accessors[prop][:get].(this)
  elsif properties.has_key? prop
    properties[prop]
  else
    prototype && prototype.is_a?(Object) ? prototype.get(prop, this) : Undefined.new
  end
end

#get_own_property(prop) ⇒ Object



63
64
65
66
67
68
69
70
71
# File 'lib/twostroke/runtime/types/object.rb', line 63

def get_own_property(prop)
  if accessors.has_key? prop
    accessors[prop][:get] ? accessors[prop][:get].(this) : Undefined.new
  elsif properties.has_key? prop
    properties[prop]
  else
    Undefined.new
  end
end

#get_property(prop) ⇒ Object



73
74
75
# File 'lib/twostroke/runtime/types/object.rb', line 73

def get_property(prop)
  # @TODO?
end

#has_accessor(prop) ⇒ Object



110
111
112
# File 'lib/twostroke/runtime/types/object.rb', line 110

def has_accessor(prop)
  accessors.has_key?(prop)
end

#has_own_property(prop) ⇒ Object



114
115
116
# File 'lib/twostroke/runtime/types/object.rb', line 114

def has_own_property(prop)
  accessors.has_key?(prop) || properties.has_key?(prop)
end

#has_property(prop) ⇒ Object



106
107
108
# File 'lib/twostroke/runtime/types/object.rb', line 106

def has_property(prop)
  accessors.has_key?(prop) || properties.has_key?(prop) || (prototype && prototype.is_a?(Object) && prototype.has_property(prop))
end

#proto_put(prop, value) ⇒ Object

puts prop as a non-enumerable property



98
99
100
# File 'lib/twostroke/runtime/types/object.rb', line 98

def proto_put(prop, value)
  define_own_property prop, value: value, enumerable: false
end

#put(prop, value, this = self) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
# File 'lib/twostroke/runtime/types/object.rb', line 85

def put(prop, value, this = self)
  if accessors.has_key? prop
    accessors[prop][:set].(this, value) if accessors[prop][:set] && accessors[prop][:writable]
  elsif properties.has_key? prop
    properties[prop] = value
#      elsif prototype && prototype.is_a?(Object) && prototype.has_accessor(prop)
#        prototype.put prop, value, this
  else
    properties[prop] = value
  end
end

#to_rubyObject



16
17
18
# File 'lib/twostroke/runtime/types/object.rb', line 16

def to_ruby
  Twostroke::Context::ObjectProxy.new self
end

#typeofObject



28
29
30
# File 'lib/twostroke/runtime/types/object.rb', line 28

def typeof
  "object"
end