Module: ProductionOpenStruct

Defined in:
lib/production_open_struct.rb

Overview

Overrides OpenStruct behavior to no longer define singleton methods on each object.

Note: unlike the standard library implementation, this code does not need to use the raise! and block_given! aliases. Those aliases exist to protect OpenStruct internals from fields that shadow built in methods via singleton methods. Since this module prevents singleton methods from ever being defined, built in methods can no longer be shadowed. The aliases also don't exist in the ostruct versions bundled with Ruby <= 3.0 or on JRuby, so using them would break on those platforms.

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args) ⇒ Object (private)

:nodoc:



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/production_open_struct.rb', line 38

def method_missing(method_name, *args) # :nodoc:
  len = args.length
  if method_name.to_s.end_with?("=")
    if len != 1
      raise ArgumentError, "wrong number of arguments (given #{len}, expected 1)", caller(1)
    end
    self[method_name.to_s.chomp("=")] = args[0]
  elsif len == 0
    @table[method_name]
  else
    begin
      super
    rescue NoMethodError => err
      err.backtrace.shift
      raise
    end
  end
end

Instance Method Details

#delete_field(name, &block) ⇒ void

This method returns an undefined value.

Parameters:

  • name (Symbol, String)

    the name of the field to delete

Raises:

  • (FrozenError)


16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/production_open_struct.rb', line 16

def delete_field(name, &block)
  raise FrozenError, "can't modify frozen #{self.class}: #{inspect}" if frozen?

  sym = name.to_sym
  begin
    # Clean up stale accessors on objects created before this module was prepended.
    singleton_class.remove_method(sym, "#{sym}=")
  rescue NameError
  end
  @table.delete(sym) do
    return yield if block
    raise NameError.new("no field `#{sym}' in #{self}", sym)
  end
end