From: "Eregon (Benoit Daloze) via ruby-core" <ruby-core@ml.ruby-lang.org>
To: ruby-core@ml.ruby-lang.org
Cc: "Eregon (Benoit Daloze)" <noreply@ruby-lang.org>
Subject: [ruby-core:117235] [Ruby master Feature#20349] Pattern Matching - Expose local variable captures
Date: Tue, 19 Mar 2024 20:01:58 +0000 (UTC) [thread overview]
Message-ID: <redmine.journal-107322.20240319200157.7576@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-20349.20240319175811.7576@ruby-lang.org
Issue #20349 has been updated by Eregon (Benoit Daloze).
This would make every pattern matching a lot slower which seems a big no-no performance wise.
I think that's enough to reject this proposal.
Because it would force to create that binding/Hash eagerly in case `PatternMatch.last_match` is used later.
Actually, `$~`/`Regexp.last_match` and `$_` are already causing significant performance problems for Ruby implementations, so I am strongly against any more of these "magically create variables in the caller".
BTW the example doesn't show how this is useful, is it to print the current state for debugging?
If so a helper method taking a `binding` seems appropriate (called inside the `longform_block?` method, not outside).
----------------------------------------
Feature #20349: Pattern Matching - Expose local variable captures
https://bugs.ruby-lang.org/issues/20349#change-107322
* Author: baweaver (Brandon Weaver)
* Status: Open
----------------------------------------
In Regular Expressions we have the ability to utilize `Regexp.last_match` ([link](https://ruby-doc.org/3.2.2/Regexp.html#method-c-last_match)) to access the most recent match data from a regular expression match. I would like to propose that we have similar functionality for pattern matching:
```ruby
require "rubocop"
def ast_from(string)
case string
when String then processed_source_from(string).ast
when RuboCop::ProcessedSource then string.ast
when RuboCop::AST::Node then string
else nil
end
end
def longform_block?(node)
node in [:block, # s(:block,
[:send, target, target_method], # s(:send, s(:array), :select),
[[:arg, v]], # s(:args, s(:arg, :v)),
[:send, [:lvar, ^v], block_method] # s(:send, s(:lvar, :v), :even?))
]
end
longform_block?(ast_from("[1, 2, 3].select { |v| v.even? }"))
# => true
# Name is not important, idea is, name can be debated. `source` is used to not
# show AST nodes
PatternMatch.last_match.transform_values(&:source)
# => {:node=>"[1, 2, 3].select { |v| v.even? }",
# :result=>"[1, 2, 3].select { |v| v.even? }",
# :target=>"[1, 2, 3]",
# :target_method=>:select,
# :v=>:v,
# :block_method=>:even?}
# Hacky version to show how / where behavior could be captured
def longform_block?(node)
result = node in [:block, # s(:block,
[:send, target, target_method], # s(:send, s(:array), :select),
[[:arg, v]], # s(:args, s(:arg, :v)),
[:send, [:lvar, ^v], block_method] # s(:send, s(:lvar, :v), :even?))
]
pp(binding.local_variables.to_h { [_1, binding.local_variable_get(_1).then { |s| s.source rescue s }] })
result
end
```
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/
next prev parent reply other threads:[~2024-03-19 20:02 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-19 17:58 [ruby-core:117233] [Ruby master Feature#20349] Pattern Matching - Expose local variable captures baweaver (Brandon Weaver) via ruby-core
2024-03-19 20:01 ` Eregon (Benoit Daloze) via ruby-core [this message]
2024-03-20 8:32 ` [ruby-core:117248] " nobu (Nobuyoshi Nakada) via ruby-core
2024-03-20 11:05 ` [ruby-core:117256] " Eregon (Benoit Daloze) via ruby-core
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.ruby-lang.org/en/community/mailing-lists/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=redmine.journal-107322.20240319200157.7576@ruby-lang.org \
--to=ruby-core@ruby-lang.org \
--cc=noreply@ruby-lang.org \
--cc=ruby-core@ml.ruby-lang.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).