Skip to content
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

resolve #642 - Add Pattern Matching #643

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

baweaver
Copy link

@baweaver baweaver commented Jan 19, 2021

Resolves feature request #642 requesting the addition of Pattern
Matching hooks for Ruby 2.7+ by introducing to_h, deconstruct, and
deconstruct_keys to core classes.

This change also addresses spec changes by gating pattern matching specs
on Ruby 2.7+ to prevent failures in older versions. All specs have also
been given a pattern matching spec matching their implementation to
demonstrate potential usages.

While demonstrational usages could dive into nested classes that are in
HTTP this was avoided to keep tests isolated from eachother.

Examples of what this makes possible, among other things:

response = HTTP.get('https://jsonplaceholder.typicode.com/users')

# Array style

# Right-hand assignment
response => [status, _, body]

# Body is _long_
p status: status, body_size: body.size
# => {:status=>200, :body_size=>5645}

case response
in 200, _, body
  body.size
else
  false
end
# => 5645

# Hash style

case response
in {
  status: 200,
  body: {
    contents:  /address/ => contents,
    streaming: false,
    encoding:  Encoding::UTF_8
  },
  headers: {
    content_type: /json/,
    server:       'cloudflare'
  }
}
  [true, contents.size]
else
  [false, nil]
end
# => [true, 5645]

Resolves feature request httprb#642 requesting the addition of Pattern
Matching hooks for Ruby 2.7+ by introducing `to_h`, `deconstruct`, and
`deconstruct_keys` to core classes.

This change also addresses spec changes by gating pattern matching specs
on Ruby 2.7+ to prevent failures in older versions. All specs have also
been given a pattern matching spec matching their implementation to
demonstrate potential usages.

While demonstrational usages could dive into nested classes that are in
`HTTP` this was avoided to keep tests isolated from eachother.
@baweaver
Copy link
Author

It appears that conditional gating for Ruby 2.7+ isn't isolating these specs. I'll have to follow up with an additional commit some time tomorrow when I have time to address that.

# @return [Hash[String, Symbol]]
def underscored_keys_mapping
Hash[keys.map { |k| [k, k.tr('A-Z-', 'a-z_').to_sym] }]
end
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be unnecessary if an alternate method is available that does the same.

@baweaver
Copy link
Author

The only way I can get around "invalid" syntax that doesn't exist until 2.7 that I can think of or get to work is unfortunately very hacky:

if RUBY_VERSION >= '2.7'
  eval <<~RUBY
    [1,2,3] in [1, *]
  RUBY
end

Would love to implement this for newer versions of Ruby but can't think of anything better than that hack for the moment

@baweaver baweaver force-pushed the baweaver/pattern_matching/initial_implementation branch from d307135 to d771e35 Compare January 19, 2021 07:03
Resolves syntax errors introduced by pattern matching in older versions
of Ruby through the use of `eval` to prevent immediate evaluation of
invalid syntax.
@baweaver baweaver force-pushed the baweaver/pattern_matching/initial_implementation branch from d771e35 to 366767c Compare January 19, 2021 07:11
@baweaver
Copy link
Author

It appears that Ruby core uses a similar hack to get around old versions:

ruby/ruby@f9696ca

@ixti ixti self-requested a review January 19, 2021 17:21
@baweaver
Copy link
Author

Regarding CodeClimate I can reduce one of the methods out, but the other class not as easily. Granted my opinion is 20 methods / class is a bit arbitrary, but will defer to standards of the repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant