@@ -1535,6 +1535,99 @@ EOF
1535
1535
1536
1536
Extra explanations: [[https://stackoverflow.com/questions/1250079/how-to-escape-single-quotes-within-single-quoted-strings][StackOverflow]]
1537
1537
1538
+ ** any, every, lambdas, closures, and eval
1539
+ Bash has no closures, and it's not "functional", but we're going to
1540
+ see how we can combine some tricks and get decent high-level functions
1541
+
1542
+ Here's an implementation of =any= and =every=
1543
+
1544
+ #+begin_src bash
1545
+ any() {
1546
+ local pred="$1"; shift
1547
+ for i in "$@"; do
1548
+ if $pred $i; then
1549
+ return 0
1550
+ fi
1551
+ done
1552
+ return 1
1553
+ }
1554
+
1555
+ every() {
1556
+ local pred="$1"; shift
1557
+ for i in "$@"; do
1558
+ if ! $pred $i; then
1559
+ return 1
1560
+ fi
1561
+ done
1562
+ return 0
1563
+ }
1564
+ #+end_src
1565
+
1566
+ The usage is by passing a callback function that will return 0 or 1.
1567
+
1568
+ #+begin_src bash
1569
+ usage() {
1570
+ echo "help message"
1571
+ }
1572
+
1573
+ is_help() {
1574
+ [ "$1" = "--help" ]
1575
+ }
1576
+
1577
+ any is_help "$@" && usage
1578
+ #+end_src
1579
+
1580
+ That's already cool.
1581
+
1582
+ Did you know that functions can start also with dashes?
1583
+
1584
+ #+begin_src bash
1585
+ usage() {
1586
+ echo "help message"
1587
+ }
1588
+
1589
+ --help() {
1590
+ [ "$1" = "--help" ]
1591
+ }
1592
+
1593
+ any --help "$@" && usage
1594
+ #+end_src
1595
+
1596
+ That also works. It's kinda obfuscated a bit, but hey....
1597
+
1598
+ We can also, with the help of =eval=, create on demand functions. They
1599
+ are global, but as we're not going to multithread, we can assume it's
1600
+ ok.
1601
+
1602
+ #+begin_src bash
1603
+ usage() {
1604
+ echo "help message"
1605
+ }
1606
+
1607
+ any_eq() {
1608
+ eval "_() { [ $1 = \$1 ] ; }"
1609
+ shift
1610
+ any _ "$@"
1611
+ }
1612
+
1613
+ any_eq "--help" "$@" && usage
1614
+ # or,
1615
+ any_eq --help "$@" && usage
1616
+ #+end_src
1617
+
1618
+ And the last trick, using =command_not_found_handle=, we can get into
1619
+ a kind of rails generators for these helpers
1620
+
1621
+ #+begin_src bash
1622
+ command_not_found_handle() {
1623
+ IFS=_ read -a cmd <<<"$1"
1624
+ [ "eq" = "${cmd[0]}" ] && eval "$1() { [ \"${cmd[1]}\" = \"\$1\" ] ; }"
1625
+ "$@"
1626
+ }
1627
+ any eq_--help "$@" && usage
1628
+ #+end_src
1629
+
1630
+
1538
1631
* Interactive
1539
1632
** Save your small scripts
1540
1633
Rome wasn't built in a day, and like having a journal log, most of
@@ -1773,97 +1866,6 @@ EOF
1773
1866
echo "This bit will only be executed on the first foo call"
1774
1867
}
1775
1868
#+end_src
1776
- ** any, every, lambdas, closures, and eval
1777
- Bash has no closures, and it's not "functional", but we're going to
1778
- see how we can combine some tricks and get decent high-level functions
1779
-
1780
- Here's an implementation of =any= and =every=
1781
-
1782
- #+begin_src bash
1783
- any() {
1784
- local pred="$1"; shift
1785
- for i in "$@"; do
1786
- if $pred $i; then
1787
- return 0
1788
- fi
1789
- done
1790
- return 1
1791
- }
1792
-
1793
- every() {
1794
- local pred="$1"; shift
1795
- for i in "$@"; do
1796
- if ! $pred $i; then
1797
- return 1
1798
- fi
1799
- done
1800
- return 0
1801
- }
1802
- #+end_src
1803
-
1804
- The usage is by passing a callback function that will return 0 or 1.
1805
-
1806
- #+begin_src bash
1807
- usage() {
1808
- echo "help message"
1809
- }
1810
-
1811
- is_help() {
1812
- [ "$1" = "--help" ]
1813
- }
1814
-
1815
- any is_help "$@" && usage
1816
- #+end_src
1817
-
1818
- That's already cool.
1819
-
1820
- Did you know that functions can start also with dashes?
1821
-
1822
- #+begin_src bash
1823
- usage() {
1824
- echo "help message"
1825
- }
1826
-
1827
- --help() {
1828
- [ "$1" = "--help" ]
1829
- }
1830
-
1831
- any --help "$@" && usage
1832
- #+end_src
1833
-
1834
- That also works. It's kinda obfuscated a bit, but hey....
1835
-
1836
- We can also, with the help of =eval=, create on demand functions. They
1837
- are global, but as we're not going to multithread, we can assume it's
1838
- ok.
1839
-
1840
- #+begin_src bash
1841
- usage() {
1842
- echo "help message"
1843
- }
1844
-
1845
- any_eq() {
1846
- eval "_() { [ $1 = \$1 ] ; }"
1847
- shift
1848
- any _ "$@"
1849
- }
1850
-
1851
- any_eq "--help" "$@" && usage
1852
- # or,
1853
- any_eq --help "$@" && usage
1854
- #+end_src
1855
-
1856
- And the last trick, using =command_not_found_handle=, we can get into
1857
- a kind of rails generators for these helpers
1858
-
1859
- #+begin_src bash
1860
- command_not_found_handle() {
1861
- IFS=_ read -a cmd <<<"$1"
1862
- [ "eq" = "${cmd[0]}" ] && eval "$1() { [ \"${cmd[1]}\" = \"\$1\" ] ; }"
1863
- "$@"
1864
- }
1865
- any eq_--help "$@" && usage
1866
- #+end_src
1867
1869
1868
1870
* Debugging
1869
1871
** adding =bash= to a script to debug
0 commit comments