Class: Value
- Inherits:
-
Struct
- Object
- Struct
- Value
- Defined in:
- lib/value.rb
Overview
Value generates Struct classes with safer constructors. It is designed to provide a superset of the interface of the Values gem, with better performance, by subclassing actual native Structs.
Value constructors require all mandatory arguments to be provided, and supply default values for all optional arguments. Additionally, the resulting instance is frozen. To obtain a mutable Value, dup the result.
Value structure classes are created similarly to ‘Struct`s, with the addition that optional arguments are may be specified as keyword arguments: `ValueType = Value.new(:a, :b, c: default_value)`. The default values to optional arguments are saved at class creation time and supplied as default constructor arguments to instances. Default values are aliased, so providing mutable defaults is discouraged. Lazily-evaluated defaults can be provided by supplying `Value.lazy { … }` as a default. The lazy block will be evaluated at each instantiation time.
Two instance constructors are provided, with positional and keyword arguments.
Value types may be constructed with positional arguments using new. Arguments are provided in the same order as specified at class initialization time, with mandatory arguments before optional ones. For example: ‘ValueType.new(1, 2)`, `ValueType.new(1, 2, 3)`
Value types may be constructed with keyword arguments using with. For example: ‘ValueType.with(a: 1, b: 2, c: 3)`
Defined Under Namespace
Classes: LazyDefault
Class Method Summary collapse
Instance Method Summary collapse
Class Method Details
.lazy(&proc) ⇒ Object
70 71 72 |
# File 'lib/value.rb', line 70 def lazy(&proc) LazyDefault.new(proc) end |
.new(*required_args, **optional_args, &block) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/value.rb', line 33 def new(*required_args, **optional_args, &block) arguments = {} required_args.each { |arg| arguments[arg] = true } optional_args.each_key { |arg| arguments[arg] = false } validate_names(*arguments.keys) clazz = super(*arguments.keys, &nil) # define class and instance methods in modules so that the class can # override them keyword_constructor = generate_keyword_constructor(arguments) class_method_module = Module.new do module_eval(keyword_constructor) optional_args.each do |name, value| method_name = :"__constructor_default_#{name}" if value.is_a?(LazyDefault) define_method(method_name, &value.proc) else define_method(method_name) { value } end end end clazz.extend(class_method_module) constructor = generate_constructor(arguments) instance_method_module = Module.new do module_eval(constructor) end clazz.include(instance_method_module) # Evaluate the block in the context of the class clazz.class_eval(&block) if block_given? clazz end |
Instance Method Details
#with(**kwargs) ⇒ Object
137 138 139 140 |
# File 'lib/value.rb', line 137 def with(**kwargs) return self if kwargs.empty? self.class.with(**to_h.merge(kwargs)) end |