Class: ParameterExpansion

Inherits:
Object show all
Defined in:
lib/parameter_expansion.rb

Overview

Parameter expansion utility for markdown_exec Handles different invocation types for parameter substitution

Defined Under Namespace

Classes: NewVariable

Class Method Summary collapse

Class Method Details

.create_new_variable(name, value, assignment_code, invocation, param, unique:) ⇒ Object

Create a new variable object with details



480
481
482
483
# File 'lib/parameter_expansion.rb', line 480

def self.create_new_variable(name, value, assignment_code, invocation, param, unique:)
  unique_name = "#{name}_#{unique}"
  NewVariable.new(unique_name, value, assignment_code, invocation, param)
end

.expand_command_input(param, output_type, value, invocation, unique:) ⇒ Object

Handle command substitution input ©



406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
# File 'lib/parameter_expansion.rb', line 406

def self.expand_command_input(param, output_type, value, invocation, unique:)
  case output_type
  when 'C' # :cc= - command string
    [value, nil]
  when 'E' # :ce= - command as shell expressio
    new_var = create_new_variable(param, value, "$(#{value})", invocation, param, unique: unique)
    [new_var.name, new_var]
  when 'L', 'Q' # :cl=, :cq= - output of command evaluation
    new_var = create_new_variable(param, value, "$(#{value})", invocation, param, unique: unique)
    # wrapped so MDE will expand
    [get_variable_reference(new_var.name), new_var]
  when 'V' # :cv= - name of new variable
    new_var = create_new_variable(param, value, "$(#{value})", invocation, param, unique: unique)
    [new_var.name, new_var]
  else
    [value, nil]
  end
end

.expand_expression_input(param, output_type, value, invocation, unique: rand(1e4)) ⇒ Object

Handle evaluated expression input (E)



426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
# File 'lib/parameter_expansion.rb', line 426

def self.expand_expression_input(param, output_type, value, invocation, unique: rand(1e4))
  case output_type
  when 'C' # :ec= - VALUE as a command
    [%(printf %s "#{value}"), nil]
  when 'E' # :ee= - VALUE string
    [value, nil]
  when 'L', 'Q' # :el=, :eq= - shell expression output
    # wrapped so MDE will expand
    [%($(printf %s "#{value}")), nil]
  when 'V' # :ev= - name of new variable
    new_var = create_new_variable(param, value, %(printf %s "#{value}"), invocation, param, unique: unique)
    [new_var.name, new_var]
    # [param, new_var]
  else
    [value, nil]
  end
end

.expand_literal_input(param, output_type, value, invocation, unique:) ⇒ Object

Handle literal input (L/Q)



445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
# File 'lib/parameter_expansion.rb', line 445

def self.expand_literal_input(param, output_type, value, invocation, unique:)
  case output_type
  when 'C' # :lc= or :qc= - literal VALUE as output
    [%(printf %s "#{value}"), nil]
  when 'E' # :le= or :qe= - literal VALUE as output
    [value, nil]
  when 'L', 'Q' # :ll=, :lq=, :ql=, or :qq= - literal VALUE as output
    [value, nil]
  when 'V' # :lv= or :qv= - name of new variable
    new_var = create_new_variable(param, value, Shellwords.escape(value), invocation, param, unique: unique)
    # [param, new_var]
    [new_var.name, new_var]
  else
    [value, nil]
  end
end

.expand_parameter(param, invocation, value, unique: nil) ⇒ Array

REQ-001: Expands a parameter based on invocation type and value ARCH-003: Template method pattern - delegates to specific handlers

Invocation codes:

  • First letter: Input type (C=command, E=expression, L=literal, V=variable)

  • Second letter: Output type (C=command, E=expression, L=literal, V=variable) If second letter is missing, defaults to Q (literal)

Examples:

expand_parameter("PARAM", "cc", "ls -la") 
# => ["ls -la", nil] (command as command)

expand_parameter("PARAM", "ce", "ls -la")
# => ["${PARAM}", NewVariable object] (command as expression)

expand_parameter("PARAM", "ll", "hello world")
# => ["hello world", nil] (literal as literal)

expand_parameter("PARAM", "c", "ls -la")
# => ["ls -la", nil] (command as literal, defaults to Q)

expand_parameter("PARAM", "e", "hello world")
# => ["hello world", nil] (expression as literal, defaults to Q)

Parameters:

  • param (String)

    The parameter name to be substituted

  • invocation (String)

    The 1 or 2-letter invocation code (e.g., “c”, “cc”, “ce”, “cl”, etc.)

  • value (String)

    The value to insert into the expansion

Returns:

  • (Array)

    Array containing [expansion_string, new_variable_details]



351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
# File 'lib/parameter_expansion.rb', line 351

def self.expand_parameter(param, invocation, value, unique: nil)
  return [value, nil] if invocation.nil? || invocation.empty?

  # unique = rand(1e4) if unique.nil?
  if unique.nil?
    # unique from a global counter
    @@unique ||= 0
    @@unique += 1
    unique = @@unique
  end
  
  input_type = invocation[0]&.upcase
  output_type = invocation[1]&.upcase || 'Q'  # Default to Q if second character missing

ww 'input_type:', input_type
ww 'output_type:', output_type
  # ARCH-001: Strategy pattern for input type handling
  case input_type
  when 'C' # IMPL-001: Command substitution
    expand_command_input(param, output_type, value, invocation, unique: unique)
  when 'E' # IMPL-002: Evaluated expression
    expand_expression_input(param, output_type, value, invocation, unique: unique)
  when 'L', 'Q' # REQ-004: Literal (accept both L and Q for backward compatibility)
    expand_literal_input(param, output_type, value, invocation, unique: unique)
  when 'V' # IMPL-004: Variable reference
    expand_variable_input(param, output_type, value, invocation)
  else
    # Default to raw literal if no valid input type
    [value, nil]
  end
end

.expand_parameter_string(param, invocation, value, unique: rand(1e4)) ⇒ Object

Convenience method that returns just the expansion string (backward compatibility)



384
385
386
387
# File 'lib/parameter_expansion.rb', line 384

def self.expand_parameter_string(param, invocation, value, unique: rand(1e4))
  result, _new_var = expand_parameter(param, invocation, value, unique: unique)
  result
end

.expand_parameters(parameter_hash, unique: rand(1e4)) ⇒ Object

Process multiple parameters and collect all new variables



390
391
392
393
394
395
396
397
398
399
400
401
# File 'lib/parameter_expansion.rb', line 390

def self.expand_parameters(parameter_hash, unique: rand(1e4))
  expansions = {}
  new_variables = []
  
  parameter_hash.each do |param, (invocation, value)|
    expansion, new_var = expand_parameter(param, invocation, value, unique: unique)
    expansions[param] = expansion
    new_variables << new_var if new_var
  end
  
  [expansions, new_variables]
end

.expand_variable_input(param, output_type, value, invocation) ⇒ Object

Handle variable reference input (V)



463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
# File 'lib/parameter_expansion.rb', line 463

def self.expand_variable_input(param, output_type, value, invocation)
  case output_type
  when 'C' # :vc= - variable VALUE expanded
    [%(printf %s "#{get_value_reference(value)}"), nil]
  when 'E' # :ve= - variable VALUE as a shell expr
    [get_value_reference(value), nil]
  when 'L', 'Q' # :vl=, :vq= - variable VALUE expanded
    # wrapped so MDE will expand
    [get_value_reference(value), nil]
  when 'V' # :vv= - VALUE string
    [value, nil]
  else
    [value, nil]
  end
end

.get_value_reference(value) ⇒ Object

Get the appropriate variable reference for the value



502
503
504
# File 'lib/parameter_expansion.rb', line 502

def self.get_value_reference(value)
  value_wrapped?(value) ? value : "${#{value}}"
end

.get_variable_reference(param) ⇒ Object

Get the appropriate variable reference for the parameter



491
492
493
494
# File 'lib/parameter_expansion.rb', line 491

def self.get_variable_reference(param)
  param.start_with?('$') ? param : "${#{param}}"
  # param_wrapped?(param) ? param : "${#{param}}"
end

.param_wrapped?(param) ⇒ Boolean

Check if parameter is already wrapped with ${}

Returns:

  • (Boolean)


486
487
488
# File 'lib/parameter_expansion.rb', line 486

def self.param_wrapped?(param)
  param.start_with?('${') && param.end_with?('}')
end

.value_wrapped?(value) ⇒ Boolean

Check if value is already wrapped with ${}

Returns:

  • (Boolean)


497
498
499
# File 'lib/parameter_expansion.rb', line 497

def self.value_wrapped?(value)
  value.start_with?('${') && value.end_with?('}')
end