[ruby-core:109998] [Ruby master Feature#19015] Language extension by a heredoc
From:
"ko1 (Koichi Sasada)" <noreply@...>
Date:
2022-09-22 17:56:11 UTC
List:
ruby-core #109998
Issue #19015 has been updated by ko1 (Koichi Sasada).
This is tiny sample of SQL.
Note that I'm newbe of SQL (I goooooooogled the syntax/api and the example is never tested).
```ruby
module SQLite3HeredocExtension
def compile str
vs = []
compiled = str.gsub(/\?([a-z_][a-zA-Z\d]+)/){|m|
vs << $1
??
}
[vs, compiled]
end
# syntax
# * SQL statement
# * but ?var is replaced with the Ruby's variable
def heredoc_exntesion_SQL str, b
vs, compiled_str = compile str
stmt = @db.prepare compiled_str
@db.execute stmt, vs.map{|v| b.local_variable_get(v).to_s}
end
end
require 'sqlite3'
@db = SQLite3::Database.new "test.db"
include SQLite3HeredocExtension
results = <<!SQL
select person.name from people where person.age > ?lowest_age
SQL
## hmm, "SQL" seems to return a SQL statement...?
# AR
results = People.select(:name).where("age >= ?", lowest_age)
# AR/execute
results = ActiveRecord::Base.connection.execute("select person.name from perople where person.age > ?", lowest_age)
```
----------------------------------------
Feature #19015: Language extension by a heredoc
https://bugs.ruby-lang.org/issues/19015#change-99249
* 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 #=> <div>Hello ko1</div>
```
## 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>