Module: Ryo::Reflect
Overview
The Ryo::Reflect module mirrors
JavaScript’s Relfect
object,
and some of the static methods on JavaScript’s
Object
as well.
Ryo::Reflect also implements Ryo-specific reflection features. The instance methods of this module are available as singleton methods on the Ryo module.
JavaScript equivalents (Reflect) collapse
-
#set_prototype_of(ryo, prototype) ⇒ nil
Equivalent to JavaScript’s
Reflect.setPrototypeOf
. -
#define_property(ryo, property, value) ⇒ void
Equivalent to JavaScript’s
Reflect.defineProperty
. -
#properties_of(ryo) ⇒ Array<String>
Equivalent to JavaScript’s
Reflect.ownKeys
, and JavaScript’sObject.keys
. -
#prototype_of(ryo) ⇒ Ryo?
Equivalent to JavaScript’s
Reflect.getPrototypeOf
.
JavaScript equivalents (Object) collapse
-
#property?(ryo, property) ⇒ Boolean
Equivalent to JavaScript’s
Object.hasOwn
, andObject.prototype.hasOwnProperty
. -
#assign(target, *sources) ⇒ Ryo
Equivalent to JavaScript’s
Object.assign
.
Ryo-specific collapse
-
#inspect_object(ryo) ⇒ String
Returns a String representation of a Ryo object.
-
#prototype_chain_of(ryo) ⇒ Array<Ryo::Object, Ryo::BasicObject>
Returns the prototype chain of a Ryo object.
-
#table_of(ryo, recursive: false) ⇒ Hash
Returns the table of a Ryo object.
-
#set_table_of(ryo, table) ⇒ nil
Sets the table of a Ryo object.
-
#call_method(ryo, method, *args, &b) ⇒ ::Object, ::BasicObject
-
#class_of(ryo) ⇒ Class
Returns the class of a Ryo object.
-
#function?(obj) ⇒ Boolean
Returns true when given a Ryo function.
-
#memo?(obj) ⇒ Boolean
(also: #lazy?)
Returns true when given a Ryo memo.
-
#ryo?(obj) ⇒ Boolean
Returns true when given a Ryo object.
-
#equal?(ryo1, ryo2) ⇒ Boolean
Returns true when the two Ryo objects are strictly equal.
Instance Method Details
#inspect_object(ryo) ⇒ String
Returns a String representation of a Ryo object
253 254 255 256 257 258 259 260 |
# File 'lib/ryo/reflect.rb', line 253 def inspect_object(ryo) format( "#<Ryo object=%{object} proto=%{proto} table=%{table}>", object: Object.instance_method(:to_s).bind_call(ryo), proto: prototype_of(ryo).inspect, table: table_of(ryo).inspect ) end |
#set_prototype_of(ryo, prototype) ⇒ nil
Equivalent to JavaScript’s Reflect.setPrototypeOf
43 44 45 46 47 |
# File 'lib/ryo/reflect.rb', line 43 def set_prototype_of(ryo, prototype) kernel(:instance_variable_set) .bind_call(ryo, :@_proto, prototype) nil end |
#define_property(ryo, property, value) ⇒ void
This method returns an undefined value.
Equivalent to JavaScript’s Reflect.defineProperty
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/ryo/reflect.rb', line 59 def define_property(ryo, property, value) table, property = table_of(ryo), property.to_s kernel(:tap).bind_call(value) { _1.bind!(ryo) if function?(_1) } table[property] = value # Define setter if !setter_defined?(ryo, property) && property[-1] != "?" define_method!(ryo, "#{property}=") { ryo[property] = _1 } end # Define getter return if getter_defined?(ryo, property) define_method!(ryo, property) { |*args, &b| (args.empty? && b.nil?) ? ryo[property] : super(*args, &b) } nil end |
#properties_of(ryo) ⇒ Array<String>
Equivalent to JavaScript’s Reflect.ownKeys
, and
JavaScript’s Object.keys
84 85 86 |
# File 'lib/ryo/reflect.rb', line 84 def properties_of(ryo) table_of(ryo).keys end |
#property?(ryo, property) ⇒ Boolean
Equivalent to JavaScript’s Object.hasOwn
,
and Object.prototype.hasOwnProperty
.
103 104 105 |
# File 'lib/ryo/reflect.rb', line 103 def property?(ryo, property) table_of(ryo).key?(property.to_s) end |
#assign(target, *sources) ⇒ Ryo
Equivalent to JavaScript’s Object.assign
.
117 118 119 120 121 122 |
# File 'lib/ryo/reflect.rb', line 117 def assign(target, *sources) sources.each do |source| to_hash(source).each { target[_1.to_s] = _2 } end target end |
#prototype_chain_of(ryo) ⇒ Array<Ryo::Object, Ryo::BasicObject>
Returns the prototype chain of a Ryo object
133 134 135 136 137 138 139 140 141 |
# File 'lib/ryo/reflect.rb', line 133 def prototype_chain_of(ryo) prototypes = [] loop do ryo = prototype_of(ryo) break unless ryo prototypes.push(ryo) end prototypes end |
#table_of(ryo, recursive: false) ⇒ Hash
Returns the table of a Ryo object
151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/ryo/reflect.rb', line 151 def table_of(ryo, recursive: false) table = kernel(:instance_variable_get).bind_call(ryo, :@_table) if recursive table.each do |key, value| if ryo?(value) table[key] = table_of(value, recursive:) elsif value.respond_to?(:each) table[key] = value.respond_to?(:each_pair) ? value : value.map { table_of(_1, recursive:) } end end end table end |
#set_table_of(ryo, table) ⇒ nil
Sets the table of a Ryo object
174 175 176 177 178 |
# File 'lib/ryo/reflect.rb', line 174 def set_table_of(ryo, table) kernel(:instance_variable_set) .bind_call(ryo, :@_table, table) nil end |
#call_method(ryo, method, *args, &b) ⇒ ::Object, ::BasicObject
190 191 192 193 |
# File 'lib/ryo/reflect.rb', line 190 def call_method(ryo, method, *args, &b) kernel(:__send__) .bind_call(ryo, method, *args, &b) end |
#class_of(ryo) ⇒ Class
Returns the class of a Ryo object
200 201 202 |
# File 'lib/ryo/reflect.rb', line 200 def class_of(ryo) kernel(:class).bind_call(ryo) end |
#function?(obj) ⇒ Boolean
Returns true when given a Ryo function
209 210 211 |
# File 'lib/ryo/reflect.rb', line 209 def function?(obj) Ryo::Function === obj end |
#memo?(obj) ⇒ Boolean Also known as: lazy?
Returns true when given a Ryo memo
218 219 220 |
# File 'lib/ryo/reflect.rb', line 218 def memo?(obj) Ryo::Memo === obj end |
#ryo?(obj) ⇒ Boolean
Returns true when given a Ryo object
233 234 235 |
# File 'lib/ryo/reflect.rb', line 233 def ryo?(obj) Ryo === obj end |
#equal?(ryo1, ryo2) ⇒ Boolean
Returns true when the two Ryo objects are strictly equal
244 245 246 |
# File 'lib/ryo/reflect.rb', line 244 def equal?(ryo1, ryo2) kernel(:equal?).bind_call(ryo1, ryo2) end |
#prototype_of(ryo) ⇒ Ryo?
Equivalent to JavaScript’s Reflect.getPrototypeOf
28 29 30 31 |
# File 'lib/ryo/reflect.rb', line 28 def prototype_of(ryo) kernel(:instance_variable_get) .bind_call(ryo, :@_proto) end |