http icon indicating copy to clipboard operation
http copied to clipboard

resolve #642 - Add Pattern Matching

Open baweaver opened this issue 5 years ago • 4 comments

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]

baweaver avatar Jan 19 '21 06:01 baweaver

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.

baweaver avatar Jan 19 '21 06:01 baweaver

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 avatar Jan 19 '21 06:01 baweaver

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

https://github.com/ruby/ruby/commit/f9696ca6cbfe827b7ce7199e511fa7431f9333b1

baweaver avatar Jan 19 '21 07:01 baweaver

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.

baweaver avatar Jan 19 '21 17:01 baweaver