New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support keyword arguments on all Concurrent Struct classes #738
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -197,20 +197,20 @@ def []=(member, value) | |
end | ||
|
||
# @!macro struct_new | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please update the |
||
def self.new(*args, &block) | ||
def self.new(*args, **kw_args, &block) | ||
clazz_name = nil | ||
if args.length == 0 | ||
raise ArgumentError.new('wrong number of arguments (0 for 1+)') | ||
elsif args.length > 0 && args.first.is_a?(String) | ||
clazz_name = args.shift | ||
end | ||
FACTORY.define_struct(clazz_name, args, &block) | ||
FACTORY.define_struct(clazz_name, args, kw_args, &block) | ||
end | ||
|
||
FACTORY = Class.new(Synchronization::LockableObject) do | ||
def define_struct(name, members, &block) | ||
def define_struct(name, members, kw_args, &block) | ||
synchronize do | ||
clazz = Synchronization::AbstractStruct.define_struct_class(MutableStruct, Synchronization::LockableObject, name, members, &block) | ||
clazz = Synchronization::AbstractStruct.define_struct_class(MutableStruct, Synchronization::LockableObject, name, members, kw_args, &block) | ||
members.each_with_index do |member, index| | ||
clazz.send :remove_method, member | ||
clazz.send(:define_method, member) do | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,9 +6,18 @@ module Synchronization | |
module AbstractStruct | ||
|
||
# @!visibility private | ||
def initialize(*values) | ||
def initialize(*values, **kw_values) | ||
super() | ||
ns_initialize(*values) | ||
ns_initialize(*values, **kw_values) | ||
end | ||
|
||
# @!macro [attach] struct_keyword_init | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The macro definition at the beginning of the can doc can be omitted, if the doc is not shared with other methods. |
||
# | ||
# Returns `true` if the struct uses keyword arguments. | ||
# | ||
# @return [Boolean] true if struct uses keyword arguments | ||
def keyword_init? | ||
self.class::KEYWORD_INIT | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
|
||
# @!macro [attach] struct_length | ||
|
@@ -127,13 +136,20 @@ def pr_underscore(clazz) | |
end | ||
|
||
# @!visibility private | ||
def self.define_struct_class(parent, base, name, members, &block) | ||
def self.define_struct_class(parent, base, name, members, kw_args, &block) | ||
clazz = Class.new(base || Object) do | ||
include parent | ||
self.const_set(:MEMBERS, members.collect{|member| member.to_s.to_sym}.freeze) | ||
def ns_initialize(*values) | ||
raise ArgumentError.new('struct size differs') if values.length > length | ||
@values = values.fill(nil, values.length..length-1) | ||
self.const_set(:KEYWORD_INIT, !!kw_args[:keyword_init]) | ||
def ns_initialize(*values, **kw_values) | ||
@values = if keyword_init? | ||
key_diff = kw_values.keys - members | ||
raise ArgumentError.new("unknown keywords: #{key_diff.join(',')}") unless key_diff.empty? | ||
members.map {|val| kw_values.fetch(val, nil)} | ||
else | ||
raise ArgumentError.new('struct size differs') if values.length > length | ||
values.fill(nil, values.length..length-1) | ||
end | ||
end | ||
end | ||
unless name.nil? | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to have the signature more specific
def self.new(*args, keyword_init: false, &block)
. Afaik no other keyword argument has any effect.