perl splice関数による回転 

# まえがき

splice関数で配列操作してみた。

# 参考文献

http://blog.livedoor.jp/dankogai/archives/51838970.html
https://taiga.hatenadiary.com/entry/2017/11/26/182000
https://perldoc.perl.org/functions/splice.html

# 環境

```bash
$bash --version
GNU bash, バージョン 5.0.0(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
ライセンス GPLv3+: GNU GPL バージョン 3 またはそれ以降 <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$perl --version

This is perl 5, version 30, subversion 0 (v5.30.0) built for x86_64-linux-thread

Copyright 1987-2019, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
```

# スクリプト

mock4関数

**scalar関数**で配列要素をカウント。関数内での要素数は**$#_**で参照できる。**my $ele=splice(@_,0,1);**で先頭要素を取得し、**ele**に保持。**splice(@_,\$#_+1,0,$ele);**では保持した**ele**を第2引数に指定した差し込み位置に追加。各ループごとに、末尾要素のインデックス位置に追加している。最後にループごとの処理結果をプリントアウト。

mock5関数

**$ele=splice(@_,-1);**で末尾要素を取得し、**ele**に保持。**splice(@_,0,0,\$ele);**では保持した**ele**をを第2引数に指定した差し込み位置に追加。各ループごとに、先頭要素のインデックス位置に追加している。最後にループごとの処理結果をプリントアウト。

```bash
#!/bin/bash

usage(){
  cat <<EOF
Usage:
\$echo {d..a} | ./spliceによる配列参照_with_perl.sh
ind:0,ele:c,cnt:4,liz:cbad,init_args:dcba
ind:1,ele:a,cnt:4,liz:badc,init_args:dcba
ind:2,ele:c,cnt:4,liz:adcb,init_args:dcba
ind:3,ele:a,cnt:4,liz:dcba,init_args:dcba
--------------------------------------------------------------------------------
ind:0,ele:a,cnt:4,liz:adcb,init_args:dcba
ind:1,ele:a,cnt:4,liz:badc,init_args:dcba
ind:2,ele:a,cnt:4,liz:cbad,init_args:dcba
ind:3,ele:a,cnt:4,liz:dcba,init_args:dcba
\$echo {a..d} | ./spliceによる配列参照_with_perl.sh
ind:0,ele:b,cnt:4,liz:bcda,init_args:abcd
ind:1,ele:d,cnt:4,liz:cdab,init_args:abcd
ind:2,ele:b,cnt:4,liz:dabc,init_args:abcd
ind:3,ele:d,cnt:4,liz:abcd,init_args:abcd
--------------------------------------------------------------------------------
ind:0,ele:d,cnt:4,liz:dabc,init_args:abcd
ind:1,ele:d,cnt:4,liz:cdab,init_args:abcd
ind:2,ele:d,cnt:4,liz:bcda,init_args:abcd
ind:3,ele:d,cnt:4,liz:abcd,init_args:abcd
$./spliceによる配列参照_with_perl.sh \$(echo -e '\U1f4a'{0..9})
ind:0,ele:💡,cnt:10,liz:💡💢💣💤💥💦💧💨💩💠,init_args:💠💡💢💣💤💥💦💧💨💩
ind:1,ele:💣,cnt:10,liz:💢💣💤💥💦💧💨💩💠💡,init_args:💠💡💢💣💤💥💦💧💨💩
ind:2,ele:💥,cnt:10,liz:💣💤💥💦💧💨💩💠💡💢,init_args:💠💡💢💣💤💥💦💧💨💩
ind:3,ele:💧,cnt:10,liz:💤💥💦💧💨💩💠💡💢💣,init_args:💠💡💢💣💤💥💦💧💨💩
ind:4,ele:💩,cnt:10,liz:💥💦💧💨💩💠💡💢💣💤,init_args:💠💡💢💣💤💥💦💧💨💩
ind:5,ele:💡,cnt:10,liz:💦💧💨💩💠💡💢💣💤💥,init_args:💠💡💢💣💤💥💦💧💨💩
ind:6,ele:💣,cnt:10,liz:💧💨💩💠💡💢💣💤💥💦,init_args:💠💡💢💣💤💥💦💧💨💩
ind:7,ele:💥,cnt:10,liz:💨💩💠💡💢💣💤💥💦💧,init_args:💠💡💢💣💤💥💦💧💨💩
ind:8,ele:💧,cnt:10,liz:💩💠💡💢💣💤💥💦💧💨,init_args:💠💡💢💣💤💥💦💧💨💩
ind:9,ele:💩,cnt:10,liz:💠💡💢💣💤💥💦💧💨💩,init_args:💠💡💢💣💤💥💦💧💨💩
--------------------------------------------------------------------------------
ind:0,ele:💩,cnt:10,liz:💩💠💡💢💣💤💥💦💧💨,init_args:💠💡💢💣💤💥💦💧💨💩
ind:1,ele:💩,cnt:10,liz:💨💩💠💡💢💣💤💥💦💧,init_args:💠💡💢💣💤💥💦💧💨💩
ind:2,ele:💩,cnt:10,liz:💧💨💩💠💡💢💣💤💥💦,init_args:💠💡💢💣💤💥💦💧💨💩
ind:3,ele:💩,cnt:10,liz:💦💧💨💩💠💡💢💣💤💥,init_args:💠💡💢💣💤💥💦💧💨💩
ind:4,ele:💩,cnt:10,liz:💥💦💧💨💩💠💡💢💣💤,init_args:💠💡💢💣💤💥💦💧💨💩
ind:5,ele:💩,cnt:10,liz:💤💥💦💧💨💩💠💡💢💣,init_args:💠💡💢💣💤💥💦💧💨💩
ind:6,ele:💩,cnt:10,liz:💣💤💥💦💧💨💩💠💡💢,init_args:💠💡💢💣💤💥💦💧💨💩
ind:7,ele:💩,cnt:10,liz:💢💣💤💥💦💧💨💩💠💡,init_args:💠💡💢💣💤💥💦💧💨💩
ind:8,ele:💩,cnt:10,liz:💡💢💣💤💥💦💧💨💩💠,init_args:💠💡💢💣💤💥💦💧💨💩
ind:9,ele:💩,cnt:10,liz:💠💡💢💣💤💥💦💧💨💩,init_args:💠💡💢💣💤💥💦💧💨💩
EOF
}

chk_args(){
  declare -a argv=()
  local argv=($@)
  local argc="${#argv[@]}"
  [ "${argc}" -le 1 ] && usage && exit 1
}

circle(){
  echo "$@" | xargs perl -e '
  sub mock4{
    my @init_args=@_;
    for(0..$#_){
      my $ele=splice(@_,0,1);#shift
      splice(@_,$#_+1,0,$ele);#push
      print "ind:".$_.",ele:".$_[$_].",cnt:".scalar(@_).",liz:".join("",@_).",init_args:".join("",@init_args),"\n";
    }
  }
  mock4(@ARGV);
  print "-"x80,"\n";
  sub mock5{
    my @init_args=@_;
    for(0..$#_){
      my $ele=splice(@_,-1);#pop
      splice(@_,0,0,$ele);#unshift
      print "ind:".$_.",ele:".$_[$_].",cnt:".scalar(@_).",liz:".join("",@_).",init_args:".join("",@init_args),"\n";
    }
  }
  mock5(@ARGV);
  '
}

main(){
  local init_args="$(cat -)";
  chk_args "${init_args}"
  while read ln;do circle "${ln}";done <<<"${init_args}"
}

[ -p /dev/stdin ] && cat - | main
[ -p /dev/stdin ] || echo -ne "$@" | main

```

てすと

```bash
$echo {d..a} | ./spliceによる配列参照_with_perl.sh
ind:0,ele:c,cnt:4,liz:cbad,init_args:dcba
ind:1,ele:a,cnt:4,liz:badc,init_args:dcba
ind:2,ele:c,cnt:4,liz:adcb,init_args:dcba
ind:3,ele:a,cnt:4,liz:dcba,init_args:dcba
--------------------------------------------------------------------------------
ind:0,ele:a,cnt:4,liz:adcb,init_args:dcba
ind:1,ele:a,cnt:4,liz:badc,init_args:dcba
ind:2,ele:a,cnt:4,liz:cbad,init_args:dcba
ind:3,ele:a,cnt:4,liz:dcba,init_args:dcba
$echo {a..d} | ./spliceによる配列参照_with_perl.sh
ind:0,ele:b,cnt:4,liz:bcda,init_args:abcd
ind:1,ele:d,cnt:4,liz:cdab,init_args:abcd
ind:2,ele:b,cnt:4,liz:dabc,init_args:abcd
ind:3,ele:d,cnt:4,liz:abcd,init_args:abcd
--------------------------------------------------------------------------------
ind:0,ele:d,cnt:4,liz:dabc,init_args:abcd
ind:1,ele:d,cnt:4,liz:cdab,init_args:abcd
ind:2,ele:d,cnt:4,liz:bcda,init_args:abcd
ind:3,ele:d,cnt:4,liz:abcd,init_args:abcd
```

```bash
$./spliceによる配列参照_with_perl.sh $(echo -e '\U1f4a'{0..9})
ind:0,ele:💡,cnt:10,liz:💡💢💣💤💥💦💧💨💩💠,init_args:💠💡💢💣💤💥💦💧💨💩
ind:1,ele:💣,cnt:10,liz:💢💣💤💥💦💧💨💩💠💡,init_args:💠💡💢💣💤💥💦💧💨💩
ind:2,ele:💥,cnt:10,liz:💣💤💥💦💧💨💩💠💡💢,init_args:💠💡💢💣💤💥💦💧💨💩
ind:3,ele:💧,cnt:10,liz:💤💥💦💧💨💩💠💡💢💣,init_args:💠💡💢💣💤💥💦💧💨💩
ind:4,ele:💩,cnt:10,liz:💥💦💧💨💩💠💡💢💣💤,init_args:💠💡💢💣💤💥💦💧💨💩
ind:5,ele:💡,cnt:10,liz:💦💧💨💩💠💡💢💣💤💥,init_args:💠💡💢💣💤💥💦💧💨💩
ind:6,ele:💣,cnt:10,liz:💧💨💩💠💡💢💣💤💥💦,init_args:💠💡💢💣💤💥💦💧💨💩
ind:7,ele:💥,cnt:10,liz:💨💩💠💡💢💣💤💥💦💧,init_args:💠💡💢💣💤💥💦💧💨💩
ind:8,ele:💧,cnt:10,liz:💩💠💡💢💣💤💥💦💧💨,init_args:💠💡💢💣💤💥💦💧💨💩
ind:9,ele:💩,cnt:10,liz:💠💡💢💣💤💥💦💧💨💩,init_args:💠💡💢💣💤💥💦💧💨💩
--------------------------------------------------------------------------------
ind:0,ele:💩,cnt:10,liz:💩💠💡💢💣💤💥💦💧💨,init_args:💠💡💢💣💤💥💦💧💨💩
ind:1,ele:💩,cnt:10,liz:💨💩💠💡💢💣💤💥💦💧,init_args:💠💡💢💣💤💥💦💧💨💩
ind:2,ele:💩,cnt:10,liz:💧💨💩💠💡💢💣💤💥💦,init_args:💠💡💢💣💤💥💦💧💨💩
ind:3,ele:💩,cnt:10,liz:💦💧💨💩💠💡💢💣💤💥,init_args:💠💡💢💣💤💥💦💧💨💩
ind:4,ele:💩,cnt:10,liz:💥💦💧💨💩💠💡💢💣💤,init_args:💠💡💢💣💤💥💦💧💨💩
ind:5,ele:💩,cnt:10,liz:💤💥💦💧💨💩💠💡💢💣,init_args:💠💡💢💣💤💥💦💧💨💩
ind:6,ele:💩,cnt:10,liz:💣💤💥💦💧💨💩💠💡💢,init_args:💠💡💢💣💤💥💦💧💨💩
ind:7,ele:💩,cnt:10,liz:💢💣💤💥💦💧💨💩💠💡,init_args:💠💡💢💣💤💥💦💧💨💩
ind:8,ele:💩,cnt:10,liz:💡💢💣💤💥💦💧💨💩💠,init_args:💠💡💢💣💤💥💦💧💨💩
ind:9,ele:💩,cnt:10,liz:💠💡💢💣💤💥💦💧💨💩,init_args:💠💡💢💣💤💥💦💧💨💩
```

# あとがき

perlは自由でおもしろい。


# 20191111追記

アート作成してみた。こういうのつくろうとおもうと好奇心や探究心湧いて楽しい。

```bash
$cat left_stair.sh
#!/bin/bash

usage(){
  cat <<EOF
Usage:
\$$0 \$(echo -e '\U1f4a'{0..9})
EOF
}

chk_args(){
  declare -a argv=()
  local argv=($@)
  local argc="${#argv[@]}"
  [ "${argc}" -le 1 ] && usage && exit 1
}

circle(){
  echo "$@" | xargs perl -e '
  sub mock4{
    my @init_args=@_;
    for(0..$#_){
      my $ele=splice(@_,0,1);#shift
      splice(@_,$#_+1,0,$ele);#push
      print join("",@_),"\n";
    }
  }
  mock4(@ARGV);
  '
}

main(){
  local init_args="$(cat -)";
  chk_args "${init_args}"
  while read ln;do circle "${ln}";done <<<"${init_args}"
}

[ -p /dev/stdin ] && cat - | main
[ -p /dev/stdin ] || echo -ne "$@" | main
```

先頭要素が末尾要素に追加されていく様子がわかる。

```bash
$echo -e '\U1f4a'{0..9} | ./left_stair.sh
💡💢💣💤💥💦💧💨💩💠
💢💣💤💥💦💧💨💩💠💡
💣💤💥💦💧💨💩💠💡💢
💤💥💦💧💨💩💠💡💢💣
💥💦💧💨💩💠💡💢💣💤
💦💧💨💩💠💡💢💣💤💥
💧💨💩💠💡💢💣💤💥💦
💨💩💠💡💢💣💤💥💦💧
💩💠💡💢💣💤💥💦💧💨
💠💡💢💣💤💥💦💧💨💩
```

```bash
$cat right_stair.sh
#!/bin/bash

usage(){
  cat <<EOF
Usage:
\$$0 \$(echo -e '\U1f4a'{0..9})
EOF
}

chk_args(){
  declare -a argv=()
  local argv=($@)
  local argc="${#argv[@]}"
  [ "${argc}" -le 1 ] && usage && exit 1
}

circle(){
  echo "$@" | xargs perl -e '
  sub mock5{
    my @init_args=@_;
    for(0..$#_){
      my $ele=splice(@_,-1);#pop
      splice(@_,0,0,$ele);#unshift
      print join("",@_),"\n";
    }
  }
  mock5(@ARGV);
  '
}

main(){
  local init_args="$(cat -)";
  chk_args "${init_args}"
  while read ln;do circle "${ln}";done <<<"${init_args}"
}

[ -p /dev/stdin ] && cat - | main
[ -p /dev/stdin ] || echo -ne "$@" | main
```


末尾要素が先頭要素に追加されていく様子がわかる。

```bash
$echo -e '\U1f4a'{0..9} | ./right_stair.sh
💩💠💡💢💣💤💥💦💧💨
💨💩💠💡💢💣💤💥💦💧
💧💨💩💠💡💢💣💤💥💦
💦💧💨💩💠💡💢💣💤💥
💥💦💧💨💩💠💡💢💣💤
💤💥💦💧💨💩💠💡💢💣
💣💤💥💦💧💨💩💠💡💢
💢💣💤💥💦💧💨💩💠💡
💡💢💣💤💥💦💧💨💩💠
💠💡💢💣💤💥💦💧💨💩

```

```bash
$cat square.sh
#!/bin/bash

usage(){
  cat <<EOF
Usage:
\$$0 \$(echo -e '\U1f4a'{0..9})
EOF
}

chk_args(){
  declare -a argv=()
  local argv=($@)
  local argc="${#argv[@]}"
  [ "${argc}" -le 1 ] && usage && exit 1
}

circle(){
  paste -d' ' <(./left_stair.sh $(echo -e "$@")) <(./right_stair.sh $(echo -e "$@"|rev))
  paste -d' ' <(./right_stair.sh $(echo -e "$@")) <(./left_stair.sh $(echo -e "$@"|rev))
}

main(){
  local init_args="$(cat -)";
  chk_args "${init_args}"
  while read ln;do circle "${ln}";done <<<"${init_args}"
}

[ -p /dev/stdin ] && cat - | main
[ -p /dev/stdin ] || echo -ne "$@" | main
```

きれいだ。

```bash
$echo -e '\U1f4a'{0..9} | ./square.sh
💡💢💣💤💥💦💧💨💩💠 💠💩💨💧💦💥💤💣💢💡
💢💣💤💥💦💧💨💩💠💡 💡💠💩💨💧💦💥💤💣💢
💣💤💥💦💧💨💩💠💡💢 💢💡💠💩💨💧💦💥💤💣
💤💥💦💧💨💩💠💡💢💣 💣💢💡💠💩💨💧💦💥💤
💥💦💧💨💩💠💡💢💣💤 💤💣💢💡💠💩💨💧💦💥
💦💧💨💩💠💡💢💣💤💥 💥💤💣💢💡💠💩💨💧💦
💧💨💩💠💡💢💣💤💥💦 💦💥💤💣💢💡💠💩💨💧
💨💩💠💡💢💣💤💥💦💧 💧💦💥💤💣💢💡💠💩💨
💩💠💡💢💣💤💥💦💧💨 💨💧💦💥💤💣💢💡💠💩
💠💡💢💣💤💥💦💧💨💩 💩💨💧💦💥💤💣💢💡💠
💩💠💡💢💣💤💥💦💧💨 💨💧💦💥💤💣💢💡💠💩
💨💩💠💡💢💣💤💥💦💧 💧💦💥💤💣💢💡💠💩💨
💧💨💩💠💡💢💣💤💥💦 💦💥💤💣💢💡💠💩💨💧
💦💧💨💩💠💡💢💣💤💥 💥💤💣💢💡💠💩💨💧💦
💥💦💧💨💩💠💡💢💣💤 💤💣💢💡💠💩💨💧💦💥
💤💥💦💧💨💩💠💡💢💣 💣💢💡💠💩💨💧💦💥💤
💣💤💥💦💧💨💩💠💡💢 💢💡💠💩💨💧💦💥💤💣
💢💣💤💥💦💧💨💩💠💡 💡💠💩💨💧💦💥💤💣💢
💡💢💣💤💥💦💧💨💩💠 💠💩💨💧💦💥💤💣💢💡
💠💡💢💣💤💥💦💧💨💩 💩💨💧💦💥💤💣💢💡💠
```