[#108771] [Ruby master Bug#18816] Ractor segfaulting MacOS 12.4 (aarch64 / M1 processor) — "brodock (Gabriel Mazetto)" <noreply@...>

Issue #18816 has been reported by brodock (Gabriel Mazetto).

8 messages 2022/06/05

[#108802] [Ruby master Feature#18821] Expose Pattern Matching interfaces in core classes — "baweaver (Brandon Weaver)" <noreply@...>

Issue #18821 has been reported by baweaver (Brandon Weaver).

9 messages 2022/06/08

[#108822] [Ruby master Feature#18822] Ruby lack a proper method to percent-encode strings for URIs (RFC 3986) — "byroot (Jean Boussier)" <noreply@...>

Issue #18822 has been reported by byroot (Jean Boussier).

18 messages 2022/06/09

[#108937] [Ruby master Bug#18832] Suspicious superclass mismatch — "fxn (Xavier Noria)" <noreply@...>

Issue #18832 has been reported by fxn (Xavier Noria).

16 messages 2022/06/15

[#108976] [Ruby master Misc#18836] DevMeeting-2022-07-21 — "mame (Yusuke Endoh)" <noreply@...>

Issue #18836 has been reported by mame (Yusuke Endoh).

12 messages 2022/06/17

[#109043] [Ruby master Bug#18876] OpenSSL is not available with `--with-openssl-dir` — "Gloomy_meng (Gloomy Meng)" <noreply@...>

Issue #18876 has been reported by Gloomy_meng (Gloomy Meng).

18 messages 2022/06/23

[#109052] [Ruby master Bug#18878] parse.y: Foo::Bar {} is inconsistently rejected — "qnighy (Masaki Hara)" <noreply@...>

Issue #18878 has been reported by qnighy (Masaki Hara).

9 messages 2022/06/26

[#109055] [Ruby master Bug#18881] IO#read_nonblock raises IOError when called following buffered character IO — "javanthropus (Jeremy Bopp)" <noreply@...>

Issue #18881 has been reported by javanthropus (Jeremy Bopp).

9 messages 2022/06/26

[#109063] [Ruby master Bug#18882] File.read cuts off a text file with special characters when reading it on MS Windows — magynhard <noreply@...>

Issue #18882 has been reported by magynhard (Matth辰us Johannes Beyrle).

15 messages 2022/06/27

[#109081] [Ruby master Feature#18885] Long lived fork advisory API (potential Copy on Write optimizations) — "byroot (Jean Boussier)" <noreply@...>

Issue #18885 has been reported by byroot (Jean Boussier).

23 messages 2022/06/28

[#109083] [Ruby master Bug#18886] Struct aref and aset don't trigger any tracepoints. — "ioquatix (Samuel Williams)" <noreply@...>

Issue #18886 has been reported by ioquatix (Samuel Williams).

8 messages 2022/06/29

[#109095] [Ruby master Misc#18888] Migrate ruby-lang.org mail services to Google Domains and Google Workspace — "shugo (Shugo Maeda)" <noreply@...>

Issue #18888 has been reported by shugo (Shugo Maeda).

16 messages 2022/06/30

[ruby-core:108813] [Ruby master Feature#18821] Expose Pattern Matching interfaces in core classes

From: "baweaver (Brandon Weaver)" <noreply@...>
Date: 2022-06-09 04:58:21 UTC
List: ruby-core #108813
Issue #18821 has been updated by baweaver (Brandon Weaver).


I have opened one PR against CSV: https://github.com/ruby/ruby/pull/5994

I have noted the potential precedent this may set in the PR, and the larger later discussion on whether or not we treat pattern matching keys as `Symbol`s (literal interpretation) or as keywords that we can reasonably infer on `String`-like structures. That, of course, is a much larger discussion.

The CSV change I believe does not cross the line into that larger discussion.

----------------------------------------
Feature #18821: Expose Pattern Matching interfaces in core classes
https://bugs.ruby-lang.org/issues/18821#change-97888

* Author: baweaver (Brandon Weaver)
* Status: Open
* Priority: Normal
----------------------------------------
## Problem Statement

Pattern matching is an exceptionally powerful feature in modern versions of Ruby, but it has one critical weakness that we should discuss:

It is only as powerful as the number of classes which implement its interfaces.

The more common these interfaces become, the more powerful pattern matching will become for everyday use in any scenario.

## Areas of Attention

That said, what are some classes in core Ruby where it may make sense to implement pattern matching interfaces, and what do we gain from them? I will provide an abbreviated list, but can look to qualify a larger list of potentials if this is of interest.

### Set

Currently `Set` does not implement `deconstruct`. Especially `Enumerable`-like and `Array` like entities make sense here:

```ruby
# Hypothetical implementation
class Set
  alias_method :deconstruct, :to_a
end

Set[1, 2, 3] in [1, 2, *]
# => true
```

### Matrix

Speaking of Array-like structures, Matrix may make sense as well:

```ruby
class Matrix
  alias_method :deconstruct, :to_a
end
# => :deconstruct

Matrix[[25, 93], [-1, 66]] in [[20..30, _], [..0, _]]
# => true
```

### CSV

In the case of headers especially this can become very powerful with `deconstruct_keys`:

```ruby
require "csv"
require "net/http"
require "json"

# Hypothetical implementation
class CSV::Row
  def deconstruct_keys(keys)
    # Symbol/String is contentious, yes, I will address in a moment
    self.to_h.transform_keys(&:to_sym)
  end
end

# Creating some sample data for example:
json_data = URI("https://jsonplaceholder.typicode.com/todos")
  .then { Net::HTTP.get(_1) }
  .then { JSON.parse(_1, symbolize_names: true) }

headers = json_data.first.keys
rows = json_data.map(&:values)

# Yes yes, hacky
csv_data = CSV.generate do |csv|
  csv << headers
  rows.each { csv << _1 }
end.then { CSV.parse(_1, headers: true) }

# But can provide very interesting results:
csv_data.select { _1 in userId: "1", completed: "true" }.size
# => 11
```

Though this one does raise the broader question of the conflation of Symbol and String keys for our convenience. Given that Ruby has a habit of coercing between the two in other cases I do not find this to be against the spirit of Ruby.

### RegExp MatchData

In a similar line of thinking to the CSV I believe this would present interesting opportunities, though does raise the question of what to do with `nil` types (perhaps return `[]` and `{}` respectively? May be hacky though)

```ruby
class MatchData
  alias_method :deconstruct, :to_a

  def deconstruct_keys(keys)
    named_captures.transform_keys(&:to_sym).slice(*keys)
  end
end

IP_REGEX = /
  (?<first_octet>\d{1,3})\.
  (?<second_octet>\d{1,3})\.
  (?<third_octet>\d{1,3})\.
  (?<fourth_octet>\d{1,3})
/x

'192.168.1.1'.match(IP_REGEX) in {
  first_octet: '198',
  fourth_octet: '1'
}
# => true
```

As with before though, we do risk setting a precedent on the conflation of Symbol and String keys when it is convenient to us, so may be worth proceeding with caution there.

### OpenStruct

Much like `Struct` I believe there's a good case to make here:

```ruby
class OpenStruct
  def deconstruct_keys(keys) = keys ? to_h.slice(*keys) : to_h
end

me = OpenStruct.new(name: 'Brandon', age: 31)
me in { name: /^B/ }
# => true
```

## Other Thoughts

I believe there is great potential in the core of Ruby to spread the pattern matching interface. The more common it becomes the more useful it will be to users.

Especially if this were to be adopted into places like Rack, Net::HTTP, JSON, and other areas where frequently more imperative deconstructions and querying are already commonly used.

I bring this up, rather than opening PRs, as I would like to see whether or not the core Ruby team is interested in these types of PRs and work of finding where else these interfaces may make sense.

If you would like my more complete thoughts on this, and considerations for pattern matching interfaces in Ruby, I had written [Pattern Matching Interfaces in Ruby](https://docs.google.com/document/d/1spnuQTKy5i7Lx-sDCsORKN981Iam1IuNdOsYkhh9Yi0/edit#) some time ago to note concerns, potential guidelines, and other considerations.



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>

In This Thread