環境は macOS 10.14.4 で go1.12.5 です。

まずは次のコードを読んでみましょう

package main import ( "fmt" "io/ioutil" ) const script = ` #!perl print "Hello, Perl World!!"; __END__ ` func init() { ioutil.Discard.Write([] byte (script)) } func main() { fmt.Println( "This is Go world!!" ) }

これをビルドして実行してみます

go build -o main main.go

こうすると main という実行用のバイナリができますね。

通常通り実行してみましょう。

$ ./main This is Go world!!

今度は Perl で実行してみましょう

$ perl -x ./main Hello, Perl World!!

ワオ！！

解説

Go のコードに記載していた文字列が使われる場合、その文字列はバイナリに含まれるようです。（将来的にコンパイラがもっと賢くなれば、こういったことはなくなるかもしれません）

ビルドした Go のバイナリを覗いてみましょう

$ strings ./main | less print " Hello, Perl World!! " ; __END__ exitsyscall: ...

といったような感じになってます。 上記のバイナリに含まれる文字列を Perl のコードとして見てみるとこんな感じになります。

#!perl print "Hello, Perl World!!" ;

ここまで分かれば今度は Perl 側の話に移ります。

Perl のコードで __END__ 以下に何を記述されても全て意味を持たないものとして扱われるので無視されます。そしてもう一つ perl -x の x オプションは #!perl の行までのテキストを全て無視するようになります。

-x[directory] ignore text before #!perl line (optionally cd to directory)

これらの条件が全て揃うことによって実行可能なバイナリを Perl スクリプトとしても扱うことが可能になるわけです。

Ruby でも同じ -x オプションがあるとのことなので是非試してみたいですね！！

協力してくださった @tompng さんありがとうございました！