ruby-method-arguments 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f98c731e8db7e8e471e0933be31868fe5551aff1a85202deec96d8c32b6b1aa7
4
+ data.tar.gz: fec0a5cfcbe4f7d120f741c24dbcf09cd8899b211b4a4cedb8f1ad4a2898b95b
5
+ SHA512:
6
+ metadata.gz: 12f76e8e6e3b6f13b0785ac28f95e2137d90267155c73f6c98e8aa07dd486485a34ffc9067d07cea3039684e46a9d77568ec032c3b920a5f3df191b9673d94a9
7
+ data.tar.gz: 3f78d6c1fc80d5370f5c18358046b3471ff77ae2f4ca5991a7d9eb601ad0c27fa36c814958bf249f9b2474eddad532635d73cbbe49f5813c44cd25906ff35dbc
data/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # method_arguments gem
2
+
3
+ With the [method_arguments](https://github.com/gorodulin/method_arguments?tab=readme-ov-file#method_arguments-gem) gem you can easily set object attributes from method arguments.
4
+
5
+ Transform this:
6
+
7
+ ```ruby
8
+ def initialize(user_entity, first_name:, last_name:, email:, phone:, dob:)
9
+ @user_entity = user_entity
10
+ @first_name = first_name
11
+ @last_name = last_name
12
+ @email = email
13
+ @phone = phone
14
+ @dob = dob
15
+ end
16
+ ```
17
+
18
+ into this streamlined version:
19
+
20
+ ```ruby
21
+ def initialize(user_entity, first_name:, last_name:, email:, phone:, dob:)
22
+ set_instance_vars(__method_args__)
23
+ end
24
+ ```
25
+
26
+ ## Features
27
+
28
+ ### 1. Reading Method Arguments
29
+
30
+ Within any method, call `__method_args__` to retrieve its arguments as a Hash.
31
+
32
+ ```ruby
33
+ def initialize(user_entity, first_name:, last_name:, age:, **kw_rest)
34
+ "Method ##{__method__} received #{__method_args__.inspect} arguments"
35
+ end
36
+ ```
37
+
38
+ <details>
39
+ <summary>Limitations</summary>
40
+ <br>
41
+
42
+ 1. Argument types `*rest` and `**keyrest` are ignored regardless of their name:
43
+
44
+ ```ruby
45
+ def initialize(arg, *arg_rest, kw_arg:, **kw_rest)
46
+ __method_args__ # returns { a: <value>, kw_arg: <value> }
47
+ end
48
+ ```
49
+
50
+ Casting unknown arbitrary arguments to instance variables is not recommended for security reasons.
51
+
52
+ 2. The method does not support [argument forwarding](https://docs.ruby-lang.org/en/3.2/syntax/methods_rdoc.html#label-Argument+Forwarding):
53
+
54
+ ```ruby
55
+ def self.call(...)
56
+ new(__method_args__).call # raises error
57
+ end
58
+ ```
59
+
60
+ </details>
61
+
62
+ ### 2. Filling instance @variables
63
+
64
+ Use `set_instance_vars(hash)` to assign instance variables from a Hash.
65
+
66
+ ### 3. Filling instance @variables using attribute writers
67
+
68
+ To leverage setters ([attribute writers](https://docs.ruby-lang.org/en/3.1/Module.html#method-i-attr_writer)), add `use_writers: true` argument. If a writer with the corresponding name exists, it will be invoked.
69
+
70
+ <details>
71
+ <summary>Example</summary>
72
+ <br>
73
+
74
+ Before:
75
+
76
+ ```ruby
77
+ def initialize(user_entity, first_name:, last_name:, age:)
78
+ @user_entity = user_entity
79
+ @first_name = first_name
80
+ @last_name = last_name
81
+ self.age = age
82
+ end
83
+
84
+ def age=(val)
85
+ @age = Integer(val)
86
+ end
87
+ ```
88
+
89
+ After:
90
+
91
+ ```ruby
92
+ def initialize(user_entity, first_name:, last_name:, age:, ...)
93
+ set_instance_vars(__method_args__, use_writers: true)
94
+ end
95
+
96
+ def age=(val)
97
+ @age = Integer(val)
98
+ end
99
+ ```
100
+ </details>
101
+
102
+ ## Installation
103
+
104
+ 1. Add to your Gemfile, then run `bundle install`:
105
+
106
+ ```ruby
107
+ gem "method_arguments"
108
+ ```
109
+
110
+ 2. Prepend your code with
111
+
112
+ ```ruby
113
+ require "method_arguments"
114
+ ```
115
+
116
+
117
+ ## Supported Ruby Versions
118
+
119
+ This gem is designed to be compatible with Ruby 2.7 and above. It has been tested on the following MRI versions:
120
+
121
+ - v2.7.2
122
+ - v3.0.3
123
+ - v3.1.2
124
+
125
+ If you encounter any issues with later versions, please feel free to report them.
126
+
@@ -0,0 +1,4 @@
1
+
2
+ module MethodArguments
3
+ VERSION = "0.1.0"
4
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MethodArguments
4
+ module InstanceMethods
5
+
6
+ def set_instance_vars(args, use_writers: false)
7
+ raise "Call this method on instances only" if self.instance_of?(Class) || self.instance_of?(Module)
8
+
9
+ args.each_pair do |name, value|
10
+ if use_writers && respond_to?(writer = :"#{name}=", true)
11
+ send(writer, value)
12
+ else
13
+ instance_variable_set("@#{name}", value)
14
+ end
15
+ end
16
+ end
17
+
18
+ end
19
+
20
+ module BindingMethods
21
+ # See https://bugs.ruby-lang.org/issues/18487
22
+ define_method :__method_args__, ::Kernel::method(:binding) >> ->(bng) {
23
+ caller_info = caller_locations(1,1)[0]
24
+ caller_method_name = caller_info.base_label
25
+ begin
26
+ params = bng.receiver.method(caller_method_name).parameters.map do |type, varname|
27
+ (type == :keyrest || type == :rest || type == :block) ? nil : varname
28
+ end.compact
29
+ params.map { |varname| [varname, bng.local_variable_get(varname)] }.to_h
30
+ rescue NameError => err
31
+ raise err unless err.message.start_with?("undefined method `<")
32
+ raise RuntimeError, "__method_args__ called outside method", cause: nil
33
+ end
34
+ }
35
+ end
36
+ end
37
+
38
+ Object.include MethodArguments::BindingMethods unless Object.included_modules.include?(MethodArguments::BindingMethods)
39
+ Object.include MethodArguments::InstanceMethods unless Object.included_modules.include?(MethodArguments::InstanceMethods)
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-method-arguments
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Vladimir Gorodulin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-03-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.1'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.1'
27
+ description: |
28
+ The 'method_arguments' gem simplifies the process of setting object attributes from method arguments in Ruby.
29
+ It introduces a streamlined approach to assign instance variables directly from method arguments with minimal boilerplate code.
30
+ This utility is especially useful in constructors or methods with numerous parameters, enhancing code readability and maintainability.
31
+ email:
32
+ - ru.hostmaster@gmail.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - README.md
38
+ - lib/method_arguments.rb
39
+ - lib/method_arguments/version.rb
40
+ homepage: https://github.com/gorodulin/method_arguments
41
+ licenses:
42
+ - MIT
43
+ metadata:
44
+ changelog_uri: https://github.com/gorodulin/method_arguments/CHANGELOG.md
45
+ homepage_uri: https://github.com/gorodulin/method_arguments
46
+ source_code_uri: https://github.com/gorodulin/method_arguments
47
+ rubygems_mfa_required: 'true'
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 2.7.0
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubygems_version: 3.2.32
64
+ signing_key:
65
+ specification_version: 4
66
+ summary: Read method arguments and assign instance variables
67
+ test_files: []