syntax/assignment_order.rb
tests/_examples/syntax/assignment_order.rb in the metorex repository.
# Assignment evaluates the receiver, subscripts, and namespace of each target
# before the right-hand side, and a compound assignment reads and writes
# through one evaluation of the receiver.
class Recorder
attr_reader :log
def initialize
@log = []
end
def note(step, value)
@log << step
value
end
end
class Box
attr_accessor :count
def initialize
@slots = {}
end
def [](key)
@slots[key]
end
def []=(key, value)
@slots[key] = value
end
end
module Settings
LIMIT = 1
end
recorder = Recorder.new
box = Box.new
recorder.note(:receiver, box).count = recorder.note(:value, 1)
p(recorder.log)
recorder = Recorder.new
recorder.note(:receiver, box)[recorder.note(:key, :a)] = recorder.note(:value, 2)
p(recorder.log)
recorder = Recorder.new
recorder.note(:namespace, Settings)::WIDTH = recorder.note(:value, 80)
p(recorder.log)
p(Settings::WIDTH)
recorder = Recorder.new
recorder.note(:a, box).count, recorder.note(:b, box)[:b] = recorder.note(:c, 3), recorder.note(:d, 4)
p(recorder.log)
recorder = Recorder.new
(recorder.note(:a, box).count, _rest), _tail = [recorder.note(:b, 5)]
p(recorder.log)
p(box.count)
recorder = Recorder.new
box.count = 1
recorder.note(:receiver, box).count += 2
p(recorder.log)
p(box.count)
recorder = Recorder.new
box[:k] = 10
recorder.note(:receiver, box)[recorder.note(:key, :k)] += 5
p(recorder.log)
p(box[:k])
recorder = Recorder.new
$VERBOSE = nil
recorder.note(:namespace, Settings)::LIMIT += 1
p(recorder.log)
p(Settings::LIMIT)
box.count = nil
box.count ||= 7
box.count ||= 8
p(box.count)
box.count &&= 9
p(box.count)
box.count = [1]
box.count <<= 2
p(box.count)
Settings::DEPTH ||= 4
p(Settings::DEPTH)
target = nil
p(target&.count = recorder.note(:unreached, 1))
p(target&.count += 1)
single = Object.new
def single.[]=(key, value)
puts("single #{key} #{value}")
end
single[:x] = 1
begin
(:not_a_module)::A = 1
rescue TypeError => error
p(error.message)
end
class Guarded
def initialize
@amount = 0
end
def bump
self.amount += 1
end
private
attr_accessor :amount
end
guarded = Guarded.new
p(guarded.bump)
begin
guarded.amount += 1
rescue NoMethodError => error
p(error.class)
end
holder = Box.new
block = proc {}
begin
eval("holder[:a, &block] = 1")
rescue SyntaxError => error
p(error.message.include?("block arg given in index assignment"))
end
begin
eval("holder[1, b: 2] += 1")
rescue SyntaxError => error
p(error.message.include?("keyword arg given in index assignment"))
end
class << Settings
attr_accessor :level
end
Settings.level = 1
Settings.level += 1
p(Settings.level)
absent = nil
begin
raise(ArgumentError, "bad width")
rescue => absent&.error
p(absent)
end
begin
eval("box.fetch(1) = 2")
rescue SyntaxError
p(SyntaxError)
end
Output:
[:receiver, :value]
[:receiver, :key, :value]
[:namespace, :value]
80
[:a, :b, :c, :d]
[:a, :b]
5
[:receiver]
3
[:receiver, :key]
15
[:namespace]
2
7
9
[1, 2]
4
nil
nil
single x 1
":not_a_module is not a class/module"
1
NoMethodError
true
true
2
nil
SyntaxError