ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:109985] [Ruby master Feature#19015] Language extension by a heredoc
@ 2022-09-22  3:22 ko1 (Koichi Sasada)
  2022-09-22  7:38 ` [ruby-core:109992] " ko1 (Koichi Sasada)
                   ` (12 more replies)
  0 siblings, 13 replies; 14+ messages in thread
From: ko1 (Koichi Sasada) @ 2022-09-22  3:22 UTC (permalink / raw)
  To: ruby-core

Issue #19015 has been reported by ko1 (Koichi Sasada).

----------------------------------------
Feature #19015: Language extension by a heredoc
https://bugs.ruby-lang.org/issues/19015

* 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--------------------------------
tmp.YubJ1EHi0O-xyzzy (2.7 KB)


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

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [ruby-core:109992] [Ruby master Feature#19015] Language extension by a heredoc
  2022-09-22  3:22 [ruby-core:109985] [Ruby master Feature#19015] Language extension by a heredoc ko1 (Koichi Sasada)
@ 2022-09-22  7:38 ` ko1 (Koichi Sasada)
  2022-09-22  8:30 ` [ruby-core:109993] " retro
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: ko1 (Koichi Sasada) @ 2022-09-22  7:38 UTC (permalink / raw)
  To: ruby-core

Issue #19015 has been updated by ko1 (Koichi Sasada).


Related I heard:

* [Template literals (Template strings) - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates) Tagged templates


----------------------------------------
Feature #19015: Language extension by a heredoc
https://bugs.ruby-lang.org/issues/19015#change-99242

* 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/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [ruby-core:109993] [Ruby master Feature#19015] Language extension by a heredoc
  2022-09-22  3:22 [ruby-core:109985] [Ruby master Feature#19015] Language extension by a heredoc ko1 (Koichi Sasada)
  2022-09-22  7:38 ` [ruby-core:109992] " ko1 (Koichi Sasada)
@ 2022-09-22  8:30 ` retro
  2022-09-22  8:46 ` [ruby-core:109994] " zverok (Victor Shepelev)
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: retro @ 2022-09-22  8:30 UTC (permalink / raw)
  To: ruby-core

Issue #19015 has been updated by retro (Josef Šimánek).


Would you mind to add also what's the output to the description? If I understand it well, following will be printed.

```
<div>Hello ko1</div>
```

Any plans already what to do when method is not implemented?

----------------------------------------
Feature #19015: Language extension by a heredoc
https://bugs.ruby-lang.org/issues/19015#change-99243

* 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/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [ruby-core:109994] [Ruby master Feature#19015] Language extension by a heredoc
  2022-09-22  3:22 [ruby-core:109985] [Ruby master Feature#19015] Language extension by a heredoc ko1 (Koichi Sasada)
  2022-09-22  7:38 ` [ruby-core:109992] " ko1 (Koichi Sasada)
  2022-09-22  8:30 ` [ruby-core:109993] " retro
@ 2022-09-22  8:46 ` zverok (Victor Shepelev)
  2022-09-22 10:51 ` [ruby-core:109997] " yugui (Yuki Sonoda)
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: zverok (Victor Shepelev) @ 2022-09-22  8:46 UTC (permalink / raw)
  To: ruby-core

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/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [ruby-core:109997] [Ruby master Feature#19015] Language extension by a heredoc
  2022-09-22  3:22 [ruby-core:109985] [Ruby master Feature#19015] Language extension by a heredoc ko1 (Koichi Sasada)
                   ` (2 preceding siblings ...)
  2022-09-22  8:46 ` [ruby-core:109994] " zverok (Victor Shepelev)
@ 2022-09-22 10:51 ` yugui (Yuki Sonoda)
  2022-09-22 17:56 ` [ruby-core:109998] " ko1 (Koichi Sasada)
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: yugui (Yuki Sonoda) @ 2022-09-22 10:51 UTC (permalink / raw)
  To: ruby-core

Issue #19015 has been updated by yugui (Yuki Sonoda).


one bikeshedding..

Usually syntax-suger in Ruby are mapped into methods whose names are very consistent with the syntax. e.g. `` ` ``, `[]=`, or `foo=`. Therefore, it is more consistent to map the new syntax into `<<!LANG` method.
It seems possible to make the lexer distinguish such a notation from `<<` symbol.

----------------------------------------
Feature #19015: Language extension by a heredoc
https://bugs.ruby-lang.org/issues/19015#change-99248

* 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/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [ruby-core:109998] [Ruby master Feature#19015] Language extension by a heredoc
  2022-09-22  3:22 [ruby-core:109985] [Ruby master Feature#19015] Language extension by a heredoc ko1 (Koichi Sasada)
                   ` (3 preceding siblings ...)
  2022-09-22 10:51 ` [ruby-core:109997] " yugui (Yuki Sonoda)
@ 2022-09-22 17:56 ` ko1 (Koichi Sasada)
  2022-09-22 23:18 ` [ruby-core:110015] " estum (Anton (estum))
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: ko1 (Koichi Sasada) @ 2022-09-22 17:56 UTC (permalink / raw)
  To: ruby-core

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/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [ruby-core:110015] [Ruby master Feature#19015] Language extension by a heredoc
  2022-09-22  3:22 [ruby-core:109985] [Ruby master Feature#19015] Language extension by a heredoc ko1 (Koichi Sasada)
                   ` (4 preceding siblings ...)
  2022-09-22 17:56 ` [ruby-core:109998] " ko1 (Koichi Sasada)
@ 2022-09-22 23:18 ` estum (Anton (estum))
  2022-09-26  4:45 ` [ruby-core:110080] " duerst
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: estum (Anton (estum)) @ 2022-09-22 23:18 UTC (permalink / raw)
  To: ruby-core

Issue #19015 has been updated by estum (Anton (estum)).


Wow, I am not the only such geek %)
My solution of the similar goal is 7 yo and it'll go to school soon.

```
$ git log lib/osascript.rb
commit 1f39d1d42b499d1424af1fa5a109ecd6ab219563 (HEAD -> master)
Author: Anton
Date:   Thu Jun 11 08:47:12 2015 +0300
```

``` ruby
# @example Simple
#   Osascript.new(<<~SCPT.freeze).()
#     activate application "Finder"
#   SCPT
#
# @example JSC with args
#   # The script takes 2 arguments: directory path & image path
#   # to set a folder icon to the given directory.
#   script = Osascript.new(<<-JS.freeze, lang: 'JavaScript')
#     ObjC.import("Cocoa");
#     function run(input) {
#       var target_path = input[0].toString();
#       var source_image = $.NSImage.alloc.initWithContentsOfFile(input[1].toString());
#       var result = $.NSWorkspace.sharedWorkspace.setIconForFileOptions(source_image, target_path, 0);
#       return target_path;
#     }
#   JS
#   script.(target_dir, folder_icon)
class Osascript
  attr_accessor :script

  def initialize(script = nil, lang: "AppleScript")
    @script = block_given? ? yield : script
    @lang = lang
  end

  def call(*other)
    handle_errors do
      cmd = ["/usr/bin/env", "osascript", *params(*other)]

      IO.popen cmd, "r+", 2 => %i(child out) do |io|
        io.write script
        io.close_write
        io.readlines
      end
    end
  end

  def params(*args)
    ["-l", @lang].tap { |e| e.concat(args.unshift(?-)) unless args.empty? }
  end

  ERROR_PATTERN = /(?<=execution error: )(.+?)(?=$)/
  USER_CANCELLED_PATTERN = /user canceled/i
  NL = "\n"

  private

  def handle_errors
    yield().each_with_object([]) do |line, buf|
      line.match(ERROR_PATTERN) { |m| raise error_for(m[0]), m[0], caller(4) }
      buf << line.strip
    end.join(NL)
  end

  def error_for(msg)
    USER_CANCELLED_PATTERN.test?(msg) ? UserCanceled : ExecutionError
  end

  class ExecutionError < RuntimeError
    CAPTURE_MSG_AND_CODE = /(.+?) \((-?\d+?)\)$/

    attr_reader :code

    def initialize(msg)
      msg.match(CAPTURE_MSG_AND_CODE) { |m| msg, @code, * = m.captures }
      super(msg)
    end
  end

  UserCanceled = Class.new(ExecutionError)
end
```

I've wrote it when I've known that cool syntax hook at the first time — an ability to pass only the opening heredoc word in closed parenthesis on single line and you can ducktype it infinitely.

Oh, and I just called in mind one more thing about heredoc: there is some tricky heredoc syntax in core source file `forwardable.rb` which brakes my brain when I try to understand it:

``` ruby
    if _valid_method?(method)
      loc, = caller_locations(2,1)
      pre = "_ ="
      mesg = "#{Module === obj ? obj : obj.class}\##{ali} at #{loc.path}:#{loc.lineno} forwarding to private method "
      method_call = "#{<<-"begin;"}\n#{<<-"end;".chomp}"
        begin;
          unless defined? _.#{method}
            ::Kernel.warn #{mesg.dump}"\#{_.class}"'##{method}', uplevel: 1
            _#{method_call}
          else
            _.#{method}(*args, &block)
          end
        end;
    end

    _compile_method("#{<<-"begin;"}\n#{<<-"end;"}", __FILE__, __LINE__+1)
    begin;
      proc do
        def #{ali}(*args, &block)
          #{pre}
          begin
            #{accessor}
          end#{method_call}
        end
      end
    end;
```

Pretty cryptic, isn't it?

----------------------------------------
Feature #19015: Language extension by a heredoc
https://bugs.ruby-lang.org/issues/19015#change-99266

* 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/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [ruby-core:110080] [Ruby master Feature#19015] Language extension by a heredoc
  2022-09-22  3:22 [ruby-core:109985] [Ruby master Feature#19015] Language extension by a heredoc ko1 (Koichi Sasada)
                   ` (5 preceding siblings ...)
  2022-09-22 23:18 ` [ruby-core:110015] " estum (Anton (estum))
@ 2022-09-26  4:45 ` duerst
  2022-09-27 18:30 ` [ruby-core:110112] " Eregon (Benoit Daloze)
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: duerst @ 2022-09-26  4:45 UTC (permalink / raw)
  To: ruby-core

Issue #19015 has been updated by duerst (Martin Dürst).


This proposal sounds interesting, but the naming looks like behind-the-scenes metaprogramming; it may be better to use a more flexible approach that doesn't fix the function name.

----------------------------------------
Feature #19015: Language extension by a heredoc
https://bugs.ruby-lang.org/issues/19015#change-99334

* 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/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [ruby-core:110112] [Ruby master Feature#19015] Language extension by a heredoc
  2022-09-22  3:22 [ruby-core:109985] [Ruby master Feature#19015] Language extension by a heredoc ko1 (Koichi Sasada)
                   ` (6 preceding siblings ...)
  2022-09-26  4:45 ` [ruby-core:110080] " duerst
@ 2022-09-27 18:30 ` Eregon (Benoit Daloze)
  2022-10-24  8:14 ` [ruby-core:110495] " ko1 (Koichi Sasada)
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Eregon (Benoit Daloze) @ 2022-09-27 18:30 UTC (permalink / raw)
  To: ruby-core

Issue #19015 has been updated by Eregon (Benoit Daloze).


This seems nice.
Would it also remove leading indentation like `<<~HEREDOC`?

----------------------------------------
Feature #19015: Language extension by a heredoc
https://bugs.ruby-lang.org/issues/19015#change-99370

* 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/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [ruby-core:110495] [Ruby master Feature#19015] Language extension by a heredoc
  2022-09-22  3:22 [ruby-core:109985] [Ruby master Feature#19015] Language extension by a heredoc ko1 (Koichi Sasada)
                   ` (7 preceding siblings ...)
  2022-09-27 18:30 ` [ruby-core:110112] " Eregon (Benoit Daloze)
@ 2022-10-24  8:14 ` ko1 (Koichi Sasada)
  2022-11-03 21:38 ` [ruby-core:110597] " dsisnero (Dominic Sisneros)
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: ko1 (Koichi Sasada) @ 2022-10-24  8:14 UTC (permalink / raw)
  To: ruby-core

Issue #19015 has been updated by ko1 (Koichi Sasada).


> Would it also remove leading indentation like <<~HEREDOC?

Sure.

----------------------------------------
Feature #19015: Language extension by a heredoc
https://bugs.ruby-lang.org/issues/19015#change-99818

* 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/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [ruby-core:110597] [Ruby master Feature#19015] Language extension by a heredoc
  2022-09-22  3:22 [ruby-core:109985] [Ruby master Feature#19015] Language extension by a heredoc ko1 (Koichi Sasada)
                   ` (8 preceding siblings ...)
  2022-10-24  8:14 ` [ruby-core:110495] " ko1 (Koichi Sasada)
@ 2022-11-03 21:38 ` dsisnero (Dominic Sisneros)
  2023-05-04  3:24 ` [ruby-core:113401] " pyromaniac (Arkadiy Zabazhanov) via ruby-core
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: dsisnero (Dominic Sisneros) @ 2022-11-03 21:38 UTC (permalink / raw)
  To: ruby-core

Issue #19015 has been updated by dsisnero (Dominic Sisneros).


It reminds me of javascript template literals and tagged templates.  Instead of passing in bindings they pass the interpolation points and the first argument is an array containing thestring split at interpolation points, and the second is the interplation values.

``` ruby
require 'cgi'

def heredoc_extension_erb strs_separated_array_at, **interpolation_points
    result = strs_separated_array.zip(interpolation_points).each_with_object([]) do |s, v, ar|
         ar << s
         ar << v if v
   end
   result.join(" ")
end

name = 'ko1'

html = <<!html
<div class="#{clsname}">Hello #{name}</div>
erb
```

I could see where this could be used to provide cmd interpolation similar to julia
``` ruby
files = ["/etc/password", "/Volumes/External HD/data.csv"]

def heredoc_ext_cmd(strs_ar, values)
   # shellescape values - 
   # if current_values is a array and curr_str ends in space and next str is nonexistant or ends in space join values with a space
   # 
   #collect cmd and cmd_args
  result = Process.new(cmd, cmd_args)
end

mycmd = <<!cmd
  grep foo #{files}
cmd

mycmd.run
```




----------------------------------------
Feature #19015: Language extension by a heredoc
https://bugs.ruby-lang.org/issues/19015#change-99928

* 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/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [ruby-core:113401] [Ruby master Feature#19015] Language extension by a heredoc
  2022-09-22  3:22 [ruby-core:109985] [Ruby master Feature#19015] Language extension by a heredoc ko1 (Koichi Sasada)
                   ` (9 preceding siblings ...)
  2022-11-03 21:38 ` [ruby-core:110597] " dsisnero (Dominic Sisneros)
@ 2023-05-04  3:24 ` pyromaniac (Arkadiy Zabazhanov) via ruby-core
  2023-05-04  4:03 ` [ruby-core:113402] " duerst via ruby-core
  2023-05-04  4:43 ` [ruby-core:113403] " pyromaniac (Arkadiy Zabazhanov) via ruby-core
  12 siblings, 0 replies; 14+ messages in thread
From: pyromaniac (Arkadiy Zabazhanov) via ruby-core @ 2023-05-04  3:24 UTC (permalink / raw)
  To: ruby-core; +Cc: pyromaniac (Arkadiy Zabazhanov)

Issue #19015 has been updated by pyromaniac (Arkadiy Zabazhanov).


Hey folks. I'm actually wondering, why don't support Elixir-like sigils in Ruby? We have a ton of them already: `%w[]`, `%r//`, so why don't just add a support for custom ones?
I'm, for once, time of writing `Date.new` or `Time.parse`, I'd like to have it `%D[2023-05-05]` or Money gem can introduce something like `%M[100 USD]` instead of the long `Money.from_amount(100, "USD")` version.

----------------------------------------
Feature #19015: Language extension by a heredoc
https://bugs.ruby-lang.org/issues/19015#change-102972

* 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/
 ______________________________________________
 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/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [ruby-core:113402] [Ruby master Feature#19015] Language extension by a heredoc
  2022-09-22  3:22 [ruby-core:109985] [Ruby master Feature#19015] Language extension by a heredoc ko1 (Koichi Sasada)
                   ` (10 preceding siblings ...)
  2023-05-04  3:24 ` [ruby-core:113401] " pyromaniac (Arkadiy Zabazhanov) via ruby-core
@ 2023-05-04  4:03 ` duerst via ruby-core
  2023-05-04  4:43 ` [ruby-core:113403] " pyromaniac (Arkadiy Zabazhanov) via ruby-core
  12 siblings, 0 replies; 14+ messages in thread
From: duerst via ruby-core @ 2023-05-04  4:03 UTC (permalink / raw)
  To: ruby-core; +Cc: duerst

Issue #19015 has been updated by duerst (Martin Dürst).





@pyromaniac I think the main problem would be how to handle namespacing. With single letters, the chance of collision is very high. How does Elixir handle this?



----------------------------------------

Feature #19015: Language extension by a heredoc

https://bugs.ruby-lang.org/issues/19015#change-102973



* 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/

 ______________________________________________
 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/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [ruby-core:113403] [Ruby master Feature#19015] Language extension by a heredoc
  2022-09-22  3:22 [ruby-core:109985] [Ruby master Feature#19015] Language extension by a heredoc ko1 (Koichi Sasada)
                   ` (11 preceding siblings ...)
  2023-05-04  4:03 ` [ruby-core:113402] " duerst via ruby-core
@ 2023-05-04  4:43 ` pyromaniac (Arkadiy Zabazhanov) via ruby-core
  12 siblings, 0 replies; 14+ messages in thread
From: pyromaniac (Arkadiy Zabazhanov) via ruby-core @ 2023-05-04  4:43 UTC (permalink / raw)
  To: ruby-core; +Cc: pyromaniac (Arkadiy Zabazhanov)

Issue #19015 has been updated by pyromaniac (Arkadiy Zabazhanov).


@duerst It is funny you asked cause I just found this 
> [Kernel] Support for multi-letter uppercase sigils
here https://hexdocs.pm/elixir/main/changelog.html
We can definitely start doing this right from the beginning.
Also, from my experience, even 1-letter sigils are not causing any issues but simplifying code reading/writing a lot.

----------------------------------------
Feature #19015: Language extension by a heredoc
https://bugs.ruby-lang.org/issues/19015#change-102974

* 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/
 ______________________________________________
 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/

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2023-05-04  4:43 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-22  3:22 [ruby-core:109985] [Ruby master Feature#19015] Language extension by a heredoc ko1 (Koichi Sasada)
2022-09-22  7:38 ` [ruby-core:109992] " ko1 (Koichi Sasada)
2022-09-22  8:30 ` [ruby-core:109993] " retro
2022-09-22  8:46 ` [ruby-core:109994] " zverok (Victor Shepelev)
2022-09-22 10:51 ` [ruby-core:109997] " yugui (Yuki Sonoda)
2022-09-22 17:56 ` [ruby-core:109998] " ko1 (Koichi Sasada)
2022-09-22 23:18 ` [ruby-core:110015] " estum (Anton (estum))
2022-09-26  4:45 ` [ruby-core:110080] " duerst
2022-09-27 18:30 ` [ruby-core:110112] " Eregon (Benoit Daloze)
2022-10-24  8:14 ` [ruby-core:110495] " ko1 (Koichi Sasada)
2022-11-03 21:38 ` [ruby-core:110597] " dsisnero (Dominic Sisneros)
2023-05-04  3:24 ` [ruby-core:113401] " pyromaniac (Arkadiy Zabazhanov) via ruby-core
2023-05-04  4:03 ` [ruby-core:113402] " duerst via ruby-core
2023-05-04  4:43 ` [ruby-core:113403] " pyromaniac (Arkadiy Zabazhanov) via ruby-core

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).