Class: Peruby::Op::DeclareList

Inherits:
Base
  • Object
show all
Defined in:
lib/peruby/op/variable.rb

Overview

Destructuring lexical declaration.

Instance Method Summary collapse

Methods inherited from Base

#argument_cells, #local_slot, #lvalue, #run_subroutine, #warning_directive?

Constructor Details

#initialize(variables, initializer, predeclared = nil) ⇒ DeclareList

Returns a new instance of DeclareList.



393
394
395
396
397
# File 'lib/peruby/op/variable.rb', line 393

def initialize(variables, initializer, predeclared = nil)
  @variables = variables
  @initializer = initializer
  @predeclared = predeclared
end

Instance Method Details

#run(env, context) ⇒ Object

rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity



400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
# File 'lib/peruby/op/variable.rb', line 400

def run(env, context)
  return declare_scalar(env, context) if @variables.length == 1 && @variables.first.first == :scalar &&
                                         @initializer.respond_to?(:first_cell)

  values = @initializer&.run(env, :list) || []
  targets = declaration_targets(env)
  return context == :list ? targets : 0 unless @initializer

  index = 0
  targets.each do |target|
    if target.is_a?(Scalar)
      target.set(values[index]&.get)
      index += 1
    elsif target.is_a?(PerlArray)
      target.cells.replace(values.drop(index).map(&:copy))
      index = values.length
    else
      target.cells.clear
      values.drop(index).each_slice(2) do |key, value|
        target.slot(Conv.to_str(key&.get)).set(value&.get)
      end
      index = values.length
    end
  end
  context == :list ? targets : values.size
end

#to_callableObject



427
428
429
430
431
432
433
434
435
436
# File 'lib/peruby/op/variable.rb', line 427

def to_callable
  return scalar_declaration_callable if @variables.length == 1 && @variables.first.first == :scalar &&
                                        @initializer.respond_to?(:first_cell_callable)

  initializer = @initializer&.to_callable
  lambda do |env, context|
    values = initializer ? initializer.call(env, :list) : []
    declare_values(env, context, values)
  end
end