Class: Peruby::Op::Element
- Inherits:
-
Base
- Object
- Base
- Peruby::Op::Element
show all
- Defined in:
- lib/peruby/op/element.rb
Overview
Array/hash access over package aggregates or references, with autovivification.
Instance Method Summary
collapse
Methods inherited from Base
#argument_cells, #local_slot, #run_subroutine, #warning_directive?
Constructor Details
#initialize(container, key, kind, dereference, **options) ⇒ Element
Returns a new instance of Element.
7
8
9
10
11
12
13
14
|
# File 'lib/peruby/op/element.rb', line 7
def initialize(container, key, kind, dereference, **options)
@container = container
@key = key
@kind = kind
@dereference = dereference
@slice = options.fetch(:slice, false)
@key_value = options.fetch(:key_value, false)
end
|
Instance Method Details
#delete(env) ⇒ Object
81
82
83
84
|
# File 'lib/peruby/op/element.rb', line 81
def delete(env)
container = aggregate(env)
keys(env).map { |key| container.delete(key) }
end
|
#exists?(env) ⇒ Boolean
76
77
78
79
|
# File 'lib/peruby/op/element.rb', line 76
def exists?(env)
container = aggregate(env)
keys(env).all? { |key| container.exists?(key) }
end
|
#localize(env, stack) ⇒ Object
86
87
88
89
90
91
92
93
94
95
96
97
|
# File 'lib/peruby/op/element.rb', line 86
def localize(env, stack)
raise PerlError, "Can't localize slice" if @slice
container = aggregate(env)
key = @key.run(env, :scalar)
key = key.get if key.respond_to?(:get)
if @kind == :array
stack.localize_array(container, Conv.to_num(key).to_i)
else
stack.localize_hash(container, Conv.to_str(key))
end
end
|
#lvalue(env, context) ⇒ Object
62
63
64
65
66
67
68
69
70
71
72
73
74
|
# File 'lib/peruby/op/element.rb', line 62
def lvalue(env, context)
container = aggregate(env)
unless @slice
key = @key.run(env, :scalar)
cell = slot(container, key.respond_to?(:get) ? key.get : key)
return context == :list ? [cell] : cell
end
keys = @key.run(env, @slice ? :list : :scalar)
keys = Array(keys).map { |key| key.respond_to?(:get) ? key.get : key }
cells = keys.map { |key| slot(container, key) }
context == :list ? cells : cells.last
end
|
#lvalue_callable ⇒ Object
49
50
51
52
53
54
55
56
57
58
59
60
|
# File 'lib/peruby/op/element.rb', line 49
def lvalue_callable
return ->(env, _key = nil) { lvalue(env, :list) } if @slice
container = aggregate_callable
kind = @kind
lambda do |env, supplied_key = nil|
key = supplied_key || @key.run(env, :scalar)
key = key.value if key.respond_to?(:value)
aggregate = container.call(env)
kind == :array ? aggregate.slot(Conv.to_num(key).to_i) : aggregate.slot(Conv.to_str(key))
end
end
|
#run(env, context) ⇒ Object
16
17
18
19
20
21
22
23
24
25
26
27
|
# File 'lib/peruby/op/element.rb', line 16
def run(env, context)
if @key_value && context == :list
container = aggregate(env)
return keys(env).flat_map { |key| [Scalar.new(Conv.to_str(key)), slot(container, key)] }
end
cells = lvalue(env, @slice ? :list : :scalar)
return cells if context == :list && cells.is_a?(Array)
cell = cells.is_a?(Array) ? cells.last : cells
context == :list ? [cell] : cell&.get
end
|
#scalar_callable ⇒ Object
40
41
42
43
44
45
46
47
|
# File 'lib/peruby/op/element.rb', line 40
def scalar_callable
return unless !@slice && !@key_value
key = @key.scalar_callable if @key.respond_to?(:scalar_callable)
key ||= ->(env) { @key.run(env, :scalar) }
lvalue = lvalue_callable
->(env) { lvalue.call(env, key.call(env))&.value }
end
|
#to_callable ⇒ Object
29
30
31
32
33
34
35
36
37
38
|
# File 'lib/peruby/op/element.rb', line 29
def to_callable
return super if @slice || @key_value
key = @key.to_callable
lvalue = lvalue_callable
lambda do |env, context|
cell = lvalue.call(env, key.call(env, :scalar))
context == :list ? [cell] : cell&.value
end
end
|