[ruby-core:109994] [Ruby master Feature#19015] Language extension by a heredoc
From:
"zverok (Victor Shepelev)" <noreply@...>
Date:
2022-09-22 08:46:33 UTC
List:
ruby-core #109994
Issue #19015 has been updated by zverok (Victor Shepelev).
I am not sure how serious this is (considering the "Apr 1" notice), but I have somewhat adjacent thought:
In many modern code editors, highlighting of several different languages in the same file is supported. Namely, SublimeText (I am not sure about the others, but I suppose the idea is not unique) understands this:
```ruby
query = <<~SQL
SELECT * FROM users WHERE status='active
SQL
DB.execute(query)
```
...and highlights the code inside a heredoc as SQL.
I am thinking that maybe some way of preserving the "tag" it was surrounded (in String metadata?.. Or, making HEREDOC-produced object a different class, a descendant of String with extra functionality) would be generically useful. It will allow implementing the @ko1 's example just like this:
```ruby
require 'erb'
def heredoc_extension_erb str, b
ERB.new(str).run(b)
end
name = 'ko1'
html = <<~erb
<div>Hello <%= name %></div>
erb
puts execute_heredoc(html, binding)
# where...
def execute_heredoc(str, binding)
case str.__tag__
when 'erb'
ERB.new(str).run(binding)
# ....
end
end
```
The idea can even be expanded to provide additional metadata (currently invalid syntax, so no compatibility would be broken):
```ruby
html = <<~erb(trim_mode="%>")
<div>Hello <%= name %></div>
erb
```
WDYT?
----------------------------------------
Feature #19015: Language extension by a heredoc
https://bugs.ruby-lang.org/issues/19015#change-99244
* Author: ko1 (Koichi Sasada)
* Status: Open
* Priority: Normal
----------------------------------------
This propose new heredoc extension with `<<!LANG` like
```ruby
doc = <<!LANG
# description written in lang LANG
foo bar
LANG
```
and it is translated to:
```ruby
doc = heredoc_extension_LANG(heredoc_text, binding)
```
## Example
```ruby
require 'erb'
def heredoc_extension_erb str, b
ERB.new(str).run(b)
end
name = 'ko1'
html = <<!erb
<div>Hello <%= name %></div>
erb
puts html
```
## Background / considerations
* Sometimes we write Ruby syntax string with `<<RUBY` and this proposal inspired by it.
* it is similar to shebang (`#!LANG` in shell)
* [Elixir's custom sigil](https://elixir-lang.org/getting-started/sigils.html) translates `~u(...)` translates to `sigil_u(...)`. This is why it translated to `heredoc_extension_LANG(...)` private method call.
* JavaScript has JSX but I don't think it is fit to the Ruby language.
* Heredoc is Ruby's chaos part and already confusing a lot. Additional chaos doesn't matter.
* `<<!foo` is valid syntax but now I don't think it is not used. gem codesearch doesn't find the usage.
* Sorry I couldn't wait 1st/Apr.
## Implementation
I attached the experimental implementation which only supports `erb` (because I couldn't find how to get delimiter to determine a method name :p).
---Files--------------------------------
heredoc_extension.patch (2.7 KB)
--
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>