<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jang Rush</title>
    <description>The latest articles on DEV Community by Jang Rush (@weakish).</description>
    <link>https://dev.to/weakish</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F141294%2F6fc48e0c-02f0-4cf0-ba0f-9abdc2430f08.jpeg</url>
      <title>DEV Community: Jang Rush</title>
      <link>https://dev.to/weakish</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/weakish"/>
    <language>en</language>
    <item>
      <title>Import Posts to dev.to via RSS</title>
      <dc:creator>Jang Rush</dc:creator>
      <pubDate>Sun, 24 May 2020 16:10:55 +0000</pubDate>
      <link>https://dev.to/weakish/import-posts-to-dev-to-via-rss-dlj</link>
      <guid>https://dev.to/weakish/import-posts-to-dev-to-via-rss-dlj</guid>
      <description>&lt;p&gt;I imported most of my articles from &lt;a href="https://mmap.page"&gt;mmap.page&lt;/a&gt; via the "Publishing to DEV from RSS" feature.&lt;/p&gt;

&lt;p&gt;The automatic import feature works.&lt;br&gt;
But there are still some issues left:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;(expected) All imported post is published today. Because I just wrote some markdown files without writing any front matter meta data, including &lt;code&gt;date&lt;/code&gt;. (Technically speaking, GitHub Pages (Jekyll) treat my markdown files as pages, not blog posts.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(expected) No syntax highlight for code blocks. Because dev.to converts HTML back to markdown, thus all &lt;code&gt;span&lt;/code&gt; tags for syntax highlight has been stripped. Anyway, there is no syntax highlight in the RSS reader either, because the RSS 2.0 specification does not support CSS style sheet and most RSS readers do not bother.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(unexpected) In some posts spaces after some punctuation marks, such as commas and periods, got stripped mystically. There may be a bug in the HTML to markdown converter used by dev.to.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(unexpected) Some posts are broken. It seems that dev.to will mistakenly treat triple backticks preceded by other characters (e.g. // ```rust) as start/end of code blocks.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So the proper way to import markdown files to dev.to is writing a script invoking the API of dev.to, which uses the markdown source directly, without the unreliable process of &lt;code&gt;markdown (source) -&amp;gt; html (rss) -&amp;gt; markdown (dev.to)&lt;/code&gt;. I will leave this trivial task to my future self.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>WireGuard Quick Start</title>
      <dc:creator>Jang Rush</dc:creator>
      <pubDate>Sun, 24 May 2020 15:36:48 +0000</pubDate>
      <link>https://dev.to/weakish/wireguard-quick-start-349c</link>
      <guid>https://dev.to/weakish/wireguard-quick-start-349c</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;WireGuard is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography.&lt;/p&gt;

&lt;p&gt;– &lt;a href="https://www.wireguard.com/"&gt;www.wireguard.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Client Side
&lt;/h2&gt;

&lt;p&gt;Install the &lt;a href="https://www.wireguard.com/install/"&gt;WireGuard package / application&lt;/a&gt; for your operating system.&lt;/p&gt;

&lt;p&gt;Create key pairs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wg genkey | tee privatekey | wg pubkey &amp;gt; publickey

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Create configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Interface]
Address = &amp;lt;private ip of virtual network&amp;gt;/32
PrivateKey = &amp;lt;content of privatekey, base64 string&amp;gt;
DNS = 1.1.1.1

[Peer]
PublicKey = &amp;lt;content of server publickey, base64 string&amp;gt;
Endpoint = &amp;lt;public ip of server:51820&amp;gt;
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Interface&lt;/code&gt; is client info, and &lt;code&gt;Peer&lt;/code&gt; is server info.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/32&lt;/code&gt; is a &lt;a href="https://doc.m0n0.ch/quickstartpc/intro-CIDR.html"&gt;subnet mask&lt;/a&gt;, which means one single IP.The client only uses one IP on the virtual network.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;DNS&lt;/code&gt; line is optional.But typically when you need to use a VPN,you probably do not want to trust DNS of your ISP.&lt;/p&gt;

&lt;p&gt;If the client is behind NAT, the router will need to translate its internal IP and port before forwarding the packets to the Internet.And the router will keep tracks of the connectinos in a Network Address Translation table.Based on this NAT table, it routinely closes off ports that appear dormant.If the router erroneously closes the WireGuard port,the WireGuard service, unaware of this change, will continue to send packets to the closed port.This leads to network problems. &lt;code&gt;PersistentKeepalive = 25&lt;/code&gt; means sending a keeplive packet to the server every 25 seconds to prevent the NAT expiration (typically in 60 seconds for most routers).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;0.0.0.0/0&lt;/code&gt; means sending all Internet and VPN traffic to this server.&lt;/p&gt;

&lt;p&gt;To enable the tunnel, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo wg-quick up /path/to/wg0.conf

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you uses a GUI WireGuard application, you can import the configuration file instead.&lt;/p&gt;

&lt;p&gt;If you uses the WireGuard mobile application, the fast way to import the configuration is scan a QR code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat /path/to/wg0.conf | qrencode -t ansiutf8

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Server Side
&lt;/h2&gt;

&lt;p&gt;Install the WireGuard package in server,then generate key pairs as mentioned above.&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;/etc/wireguard/wg0.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Interface]
Address = &amp;lt;private ip of virtual network&amp;gt;/24
PrivateKey = &amp;lt;content of privatekey, base64 string&amp;gt; 
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = &amp;lt;content of client publickey, base64 string&amp;gt; 
AllowedIPs = &amp;lt;private ip of virtual network&amp;gt;/32

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Interface&lt;/code&gt; is server info, and &lt;code&gt;Peer&lt;/code&gt; is client info.&lt;code&gt;/24&lt;/code&gt; is a subnet mask, which means the virtual network allows for up to 254 clients.&lt;code&gt;PostUp&lt;/code&gt; forwards Internet requests from clients, and &lt;code&gt;eth0&lt;/code&gt; is the network interface to access Internet on the server.&lt;code&gt;PostDown&lt;/code&gt; deletes the iptable rules when the VPN is off.Actually these are WireGuard hooks, you can fill any shell command here.&lt;/p&gt;

&lt;p&gt;You can add more clients (multiple &lt;code&gt;[Peer]&lt;/code&gt; sections).&lt;/p&gt;

&lt;p&gt;On Linux, WireGuard utilizes Linux kernel to forward packets from one network interface to another, e.g. &lt;code&gt;wg0&lt;/code&gt; to &lt;code&gt;eth0&lt;/code&gt;,since &lt;code&gt;wg0&lt;/code&gt; itself does not have Internet access.Thus we need to configure kernel parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;sysctl&lt;/code&gt; modifies kernel parameters at runtime.This is only required on the server, since client allow Internet through server.&lt;/p&gt;

&lt;p&gt;Start WireGuard:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo wg-quick up /path/to/wg0.conf

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You may also add WireGuard service to your init system, e.g. systemd:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl enable wg-quick@wg0.service

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.wireguard.com/"&gt;Official Document&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.sweeting.me/s/wireguard#"&gt;Unofficial Document&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nbsoftsolutions.com/blog/wireguard-vpn-walkthrough"&gt;WireGuard VPN Walkthrough&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>A Short Borg Tutorial</title>
      <dc:creator>Jang Rush</dc:creator>
      <pubDate>Sun, 24 May 2020 15:36:16 +0000</pubDate>
      <link>https://dev.to/weakish/a-short-borg-tutorial-5ca7</link>
      <guid>https://dev.to/weakish/a-short-borg-tutorial-5ca7</guid>
      <description>&lt;p&gt;&lt;a href="https://www.borgbackup.org/"&gt;Borg&lt;/a&gt; is the new generation of &lt;a href="https://attic-backup.org/"&gt;attic&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;borg init --encryption=keyfile /path/to/repo
borg create -C lz4 /path/to/repo::NAME-YOUR-BACKUP ~/Documents

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Free space
&lt;/h2&gt;

&lt;p&gt;Before you start creating backups,please make sure that there is always a good amount of free spaceon the filesystem that has your backup repository (and also on ~/.cache).&lt;/p&gt;

&lt;h2&gt;
  
  
  Encryption
&lt;/h2&gt;

&lt;p&gt;Default enabled with &lt;code&gt;repokey&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;borg init --encryption=none|repokey|keyfile PATH

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;When repository encryption is enabled,all data is encrypted using 256-bit AES encryptionand the integrity and authenticity is verified using HMAC-SHA256.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;repokey&lt;/code&gt;: key is stored inside the repository (&lt;code&gt;config&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;keyfile&lt;/code&gt;: key is stored under &lt;code&gt;~/.config/borg/keys/&lt;/code&gt;;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In both modes, the key is stored in encrypted formand can be only decrypted by providing the correct passphrase.&lt;/p&gt;

&lt;p&gt;Do not forget to backup the key (e.g. via &lt;code&gt;borg key export&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;For automated backups the passphrase can be specifiedusing the BORG_PASSPHRASE environment variable.&lt;/p&gt;

&lt;p&gt;Be careful how you set the environment;using the env command, a &lt;code&gt;system()&lt;/code&gt; call or using inline shell scriptsmight expose the credentials in the process list directlyand they will be readable to all users on a system.Using &lt;code&gt;export&lt;/code&gt; in a shell script file should be safe, however,as the environment of a process is accessible only to that user.Also, using a shell command may leak the passphrase in shell history file.&lt;/p&gt;

&lt;p&gt;For server backup, have a look at &lt;a href="https://torsion.org/borgmatic/"&gt;borgmatic&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compression
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;borg create --compression TYPE

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Default is no compression.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fast repo storage and some compression: &lt;code&gt;lz4&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;less fast repo storage and a bit more compression: &lt;code&gt;zlib&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;very slow repo storage and high compression: &lt;code&gt;lzma&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;lz4&lt;/code&gt; is very fast thus preferred.&lt;code&gt;lzma&lt;/code&gt; is preferred when the repository is on a remote host with slow (dial-up) connection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Upgrade from attic
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;borg upgrade --inplace REPOSITORY

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If a backup copy is required, omit the &lt;code&gt;--inplace&lt;/code&gt; option.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hosted Services
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.rsync.net/products/borg.html"&gt;rsync.net&lt;/a&gt; also works with scp, rsync, git, etc. Nodes available globally.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.borgbase.com/"&gt;BorgBase&lt;/a&gt; dedicated borg repository hosting with specific APIs. It also offers a free plan (5 GB and 2 repos), and paid plans are cheaper than rsync.net. Nodes available in US and EU.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>OSX Survival Guide</title>
      <dc:creator>Jang Rush</dc:creator>
      <pubDate>Sun, 24 May 2020 15:35:54 +0000</pubDate>
      <link>https://dev.to/weakish/osx-survival-guide-114m</link>
      <guid>https://dev.to/weakish/osx-survival-guide-114m</guid>
      <description>&lt;h2&gt;
  
  
  Bootstrap
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/MikeMcQuaid/strap"&gt;strap&lt;/a&gt; is the &lt;a href="https://mikemcquaid.com/2016/06/15/replacing-boxen/"&gt;successor of boxen&lt;/a&gt; created by the current homebrew maintainer &lt;a href="https://mikemcquaid.com"&gt;Mike McQuaid&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Download the Script
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl https://raw.githubusercontent.com/MikeMcQuaid/strap/master/bin/strap.sh &amp;gt; strap.sh

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;Edit the &lt;code&gt;strap.sh&lt;/code&gt; script, e.g. using vim, and uncomment and fill up the following environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# STRAP_GIT_NAME=
# STRAP_GIT_EMAIL=
# STRAP_GITHUB_USER=
# STRAP_GITHUB_TOKEN=
# CUSTOM_HOMEBREW_TAP=
# CUSTOM_BREW_COMMAND=

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;STRAP_GIT_NAME&lt;/code&gt; and &lt;code&gt;STRAP_GIT_EMAIL&lt;/code&gt; is to setup git &lt;code&gt;user.name&lt;/code&gt; and &lt;code&gt;user.email&lt;/code&gt;, and contact info on login screen.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;STRAP_GITHUB_USER&lt;/code&gt; is to setup git &lt;code&gt;github.user&lt;/code&gt; and to access your dotfiles and homebrew-brewfile repositories.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;STRAP_GITHUB_TOKEN&lt;/code&gt; is needed to allow homebrew to reduce the rate limit of &lt;code&gt;brew search&lt;/code&gt; command and to tap your private repositories (the token can be generated at GitHub &amp;gt; Settings &amp;gt; Developer settings &amp;gt; Personal access tokens, with scope &lt;code&gt;repo, user&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CUSTOM_HOMEBREW_TAP&lt;/code&gt; and &lt;code&gt;CUSTOM_BREW_COMMAND&lt;/code&gt; are optional, to add your personal homebrew tap and custom brew command which will be run at the end of the bootstrap.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The customized &lt;code&gt;strap.sh&lt;/code&gt; can be automatically generated at &lt;a href="https://macos-strap.herokuapp.com/,which"&gt;https://macos-strap.herokuapp.com/,which&lt;/a&gt; asks for your authorization on GitHub.But I prefer to edit the script manually.&lt;/p&gt;

&lt;p&gt;strap is idempotent, so you can run it first,adding custom dotfiles and brewfile repositories later,then run it again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Run
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/bin/bash strap.sh

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Keyboard
&lt;/h2&gt;

&lt;p&gt;In System Preference &amp;gt; Keyboard &amp;gt; Modifier Keys,&lt;code&gt;Control&lt;/code&gt; and &lt;code&gt;Command&lt;/code&gt; keys can be swapped,and &lt;code&gt;Caps&lt;/code&gt; can be used as an additional &lt;code&gt;Escape&lt;/code&gt; key.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pqrs.org/osx/karabiner/document.html#configuration-simple-modifications"&gt;Karabiner-Elements&lt;/a&gt; is a powerful keyboard modifier for osx.For example, it supports &lt;a href="https://pqrs.org/osx/karabiner/complex_modifications/#pc_shortcut"&gt;PC-style keyboard shortcuts&lt;/a&gt;.However, some of them do not work, and result in inconsistent keyboard shortcuts.It is recommend to swap &lt;code&gt;Control&lt;/code&gt; and &lt;code&gt;Command&lt;/code&gt; through Karabiner-Elements’ simple modification instead.And import certain complex rules like &lt;code&gt;Alt-Tab&lt;/code&gt; from it individually.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mouse
&lt;/h2&gt;

&lt;p&gt;Unselect “Scroll direction: Natural” in System Preferences &amp;gt; Mouse.(The direction may be natural to touch screen, but it is not natural for mouse at all.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Trackpad
&lt;/h2&gt;

&lt;p&gt;Select “Tap to click” in System Preferences &amp;gt; Trackpad.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lock Screen
&lt;/h2&gt;

&lt;p&gt;Press &lt;code&gt;Control+Shift+Power&lt;/code&gt; to turn off and lock screen.Alternatively, you can put the &lt;code&gt;Screen Lock&lt;/code&gt; icon on touch bar (System Preference &amp;gt; Keyboard &amp;gt; Touch Bar).&lt;/p&gt;

&lt;h2&gt;
  
  
  Turn off Internal Display
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;When the power adapter is connected:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Close the lid to put laptop to sleep.&lt;/li&gt;
&lt;li&gt;Reactivate laptop via external input devices, e.g. keyboard.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Tiling
&lt;/h2&gt;

&lt;p&gt;Long press the restore button, then select tiling in drop-down menu.&lt;/p&gt;

&lt;p&gt;Another way is activating mission control.Then move one window to another full screen window in another virtual desktop.&lt;/p&gt;

&lt;p&gt;Drag the edge between two tiling windows to adjust the size of the two windows at the same time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Virtual Desktops
&lt;/h2&gt;

&lt;p&gt;Press &lt;code&gt;Ctrl-Left/Right&lt;/code&gt; to switch among virtual desktops.&lt;/p&gt;

&lt;p&gt;Press &lt;code&gt;Ctrl-Up/Down&lt;/code&gt; to show an overview of desktops or go back to normal mode.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finder
&lt;/h2&gt;

&lt;p&gt;By default, &lt;code&gt;~/Library&lt;/code&gt; is hidden.To reveal it in Finder temporarily,hold the Option key, then click the &lt;code&gt;Go&lt;/code&gt; menu,and the Library fodler is revealed in the dropdown menu.&lt;/p&gt;

&lt;p&gt;To permanently reveal the Library folder in Finder, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chflags nohidden ~/Library/

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;BTW, most applications’ user configuration files are in &lt;code&gt;~/Library/Application Support&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Safari
&lt;/h2&gt;

&lt;p&gt;To enable developer tools, select “Show Develop menu in menu bar” in Safari &amp;gt; Preferences &amp;gt; Advanced.You can also change the default encoding to UTF-8.&lt;/p&gt;

&lt;p&gt;There are several vi shortcuts extensions for safari, for example, &lt;a href="https://github.com/flipxfx/sVim"&gt;sVim&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;sVim can be configured via sVimrc via the extension settings in Safari.I mapped &lt;code&gt;d&lt;/code&gt; and &lt;code&gt;D&lt;/code&gt; to close and undo close tab:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;" Shortcuts

map "d" quit
map "shift+d" lastClosedTab

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Google
&lt;/h2&gt;

&lt;p&gt;Google accounts can be added to the Mail.app.Except for the gmail, other osx applications can also sync with Google account:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Contacts&lt;/li&gt;
&lt;li&gt;Calenders&lt;/li&gt;
&lt;li&gt;Messages (with Google Talk)&lt;/li&gt;
&lt;li&gt;Notes (via gmail, tagged as notes)&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Use npm without package.json</title>
      <dc:creator>Jang Rush</dc:creator>
      <pubDate>Sun, 24 May 2020 15:35:12 +0000</pubDate>
      <link>https://dev.to/weakish/use-npm-without-package-json-3f7p</link>
      <guid>https://dev.to/weakish/use-npm-without-package-json-3f7p</guid>
      <description>&lt;h2&gt;
  
  
  Why NOT package.json?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;package.json&lt;/code&gt; brings in unnecessary complexity.If you do not think so, have a look at &lt;a href="https://pkg.go.dev/"&gt;Go&lt;/a&gt; and &lt;a href="https://deno.land/std/manual.md"&gt;Deno&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Everyday Use without package.json
&lt;/h2&gt;

&lt;p&gt;Tell npm to not save package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm config set save false

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Install development tools as global packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -g typescript
npm install -g eslint
npm i -g @zeit/ncc

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For temporal usage or test, use &lt;code&gt;npx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx cloc index.js

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;npx&lt;/code&gt; can also be used to test different node versions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx -p node@13 node -v

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Install dependencies as devDependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -D express
npm i -D @types/express

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Use &lt;a href="https://github.com/zeit/ncc/"&gt;ncc&lt;/a&gt; to package runtime dependencies into a single JavaScript file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# install dependencies according to resolved urls to tarballs in package-lock.json
@cat package-lock.json | jq '.dependencies[].resolved' | xargs npm i --no-package-lock
ncc build index.js --minify # output file: dist/index.js

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then you can move the bundled &lt;code&gt;index.js&lt;/code&gt; file to any place where Node.js is installed,and run it with &lt;code&gt;node index.js&lt;/code&gt; without installing any npm modules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Alternative to &lt;code&gt;npm run&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Just use plain old Makefile, e.g.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dist/index.js: index.js
    @cat package-lock.json | jq '.dependencies[].resolved' | xargs npm i --no-package-lock
    ncc build index.js --minify

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Pitfalls of TypeScript</title>
      <dc:creator>Jang Rush</dc:creator>
      <pubDate>Sun, 24 May 2020 15:32:09 +0000</pubDate>
      <link>https://dev.to/weakish/pitfalls-of-typescript-15pn</link>
      <guid>https://dev.to/weakish/pitfalls-of-typescript-15pn</guid>
      <description>&lt;h2&gt;
  
  
  Excess Property Checking for Object Literal
&lt;/h2&gt;

&lt;p&gt;TypeScript uses structural typing (to work with typical JavaScript code).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function print_height(person: { height: number }): void {
    console.log(person.height)
}

const somebody = { height: 150, weight: 150 };
print_height(somebody);

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;However, TypeScript has excess property checking for object literal.Thus if we inline the &lt;code&gt;somebody&lt;/code&gt; declaration above, TypeScript raises an error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;print_height({ height: 150, weight: 150 }); // Error!

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;However, partial overlap is still permitted:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Point = {
    x: number;
    y: number;
}
type Label = {
    name: string;
}
const partialOverlap: Point | Label = {
    x: 0,
    y: 0,
    name: "origin"
}
function print_pl(pl: Point | Label) {
    console.log(pl)
}
print_pl({ x: 0, y: 0, name: "origin"})

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;But overlap with conflicting properties is not permitted:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Point = {
    x: number;
    y: number;
}
type SPoint = {
    x: string;
    y: string;
}
const conflictingProperties: Point | SPoint = {x: 0, y: "0"}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Function Overloads
&lt;/h2&gt;

&lt;p&gt;Function type declaration supports overloading.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function plus(x: number, y: number): number;
function plus(x: string, y: string): string;
function plus(x: number, y: number): boolean; // see notes below
function plus(x: number | string, y: number | string): number | string | boolean { // this line is not overload
    if (typeof x == "number" &amp;amp;&amp;amp; typeof y == "number") {
        return x + y;
    } else if (typeof x == "string" &amp;amp;&amp;amp; typeof y == "string") {
        return `${x}${y}`; // equivalent to `x + y`.
    }
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the above example, the third overload will not be matched forever.Because TypeScripts looks at the overload list,proceeding with the first overload attempts to call the function with the provided parameters.If it finds a match, it picks this overload as the correct overload.And since intersection type of functions are defined as function overloads in TypeScript,this breaks the commutative rule of intersection function.Given two function types &lt;code&gt;F&lt;/code&gt; and &lt;code&gt;G&lt;/code&gt;, &lt;code&gt;F &amp;amp; G&lt;/code&gt; and &lt;code&gt;G &amp;amp; F&lt;/code&gt; are not equivalent.&lt;/p&gt;

&lt;p&gt;Not surprisingly, it is difficult to check function overloads for type equality.&lt;/p&gt;

&lt;p&gt;With TypeScript’s conditional types, testing type equality is intuitive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type EqEq&amp;lt;T, S&amp;gt; = [T] extends [S] ? ([S] extends [T] ? true : false) : false

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;But it cannot handle function overloads and function intersection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type FunctionOverloadsEquality = EqEq&amp;lt;
    { (x: 0, y: null): void; (x: number, y: null): void },
    { (x: number, y: null): void; (x: 0, y: null): void }&amp;gt; // true

type F = (x: 0, y: null) =&amp;gt; void
type G = (x: number, y: string) =&amp;gt; void
type FunctionIntersectionEquality = EqEq&amp;lt;F &amp;amp; G, G &amp;amp; F&amp;gt; // true

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To check function overloads’ type equality, use this cleaver implementation by &lt;a href="https://github.com/Microsoft/TypeScript/issues/27024#issuecomment-421529650"&gt;Matt McCutchen&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type EqEqEq&amp;lt;X, Y&amp;gt; =
    (&amp;lt;T&amp;gt;() =&amp;gt; T extends X ? 1 : 2) extends
    (&amp;lt;T&amp;gt;() =&amp;gt; T extends Y ? 1 : 2) ? true : false;

type FunctionOverloads = EqEqEq&amp;lt;
    { (x: 0, y: null): void; (x: number, y: null): void },
    { (x: number, y: null): void; (x: 0, y: null): void }&amp;gt; // false

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;However, it still cannot handle function intersection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type FunctionIntersection = EqEqEq&amp;lt;F &amp;amp; G, G &amp;amp; F&amp;gt; // true

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Besides, &lt;code&gt;EqEq&lt;/code&gt; considers &lt;code&gt;any&lt;/code&gt; to equal to any type except &lt;code&gt;never&lt;/code&gt;.This makes sense, since unlike &lt;code&gt;Any&lt;/code&gt; or &lt;code&gt;Anything&lt;/code&gt; in other languages, TypeScript’s &lt;code&gt;any&lt;/code&gt; is not a top type.&lt;code&gt;any&lt;/code&gt; is assignable to any type except &lt;code&gt;never&lt;/code&gt;.&lt;code&gt;EqEqEq&lt;/code&gt; is more strict and does not consider &lt;code&gt;any&lt;/code&gt; to be identical to other type.&lt;/p&gt;

&lt;h2&gt;
  
  
  Literal String, Literal Number, But Unique Symbol
&lt;/h2&gt;

&lt;p&gt;TypeScript has literal strings and literal numbers, but there is no literal symbols.Instead, there is unique symbols (only allowed in const declarations).&lt;/p&gt;

&lt;p&gt;In other words:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let no_unique_string_type: 'non sense but valid' = 'non sense but valid'
let no_literal_symbol: symbol = Symbol("cannot express Symbol(0) | Symbol(1)")

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
    </item>
    <item>
      <title>A Quick Introduction to React</title>
      <dc:creator>Jang Rush</dc:creator>
      <pubDate>Sun, 24 May 2020 15:31:52 +0000</pubDate>
      <link>https://dev.to/weakish/a-quick-introduction-to-react-lii</link>
      <guid>https://dev.to/weakish/a-quick-introduction-to-react-lii</guid>
      <description>&lt;h2&gt;
  
  
  Hello World
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { ReactElement } from "react"
import ReactDOM from "react-dom"

type HelloProps = { readonly name: string }

function Hello({ name }: HelloProps): ReactElement&amp;lt;HelloProps&amp;gt; {
  return &amp;lt;button&amp;gt;Hello {name}!&amp;lt;/button&amp;gt;
}

const helloWorld: ReactElement&amp;lt;HelloProps&amp;gt; = &amp;lt;Hello name="World" /&amp;gt;

const rootElement: HTMLElement = document.getElementById("root")
ReactDOM.render(helloWorld, rootElement)

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  React Components
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;Hello&lt;/code&gt; function is a React component,which receives an object containing properties,and returns a ReactElement.Here I do not plan to change the value of the &lt;code&gt;name&lt;/code&gt; property,so I annotates it as readonly.But these properties can be mutable.ReactElements can be considered as extensible html elements,or some content to be rendered.A react component may return null for conditional rendering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hooks
&lt;/h2&gt;

&lt;p&gt;Hooks decouple state related logic from components.Like components, hooks are just functions, nothing magical:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const SimpleReact = (function() {
    let state
    return {
      render(Component) {
        const C = Component()
        C.render()
        return C
      },
      useState(initialValue) {
        state = state || initialValue
        function setState(newValue) {
          state = newValue
        }
        return [state, setState]
      }
    }
})()

const useState = SimpleReact.useState
const render = SimpleReact.render

function useCountCharacters(str) {
    const [text, setText] = useState(str)
    const len = text.length
    return [len, setText]
}

function Component() {
    const [len, setLen] = useCountCharacters("")
    return {
      type: txt =&amp;gt; setLen(txt),
      render: () =&amp;gt; console.log({ len })
    }
}

let App = render(Component) // { len: 0 }
App.type('hello')
App = render(Component) // { len: 5 }

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The real React will re-render components on state changes automatically.And there are other kind of hooks, e.g. &lt;code&gt;useEffect&lt;/code&gt; for side-effects, triggered on state changes.Also, the real React can handle multiple hooks, which can be considered as &lt;a href="https://medium.com/@ryardley/react-hooks-not-magic-just-arrays-cd4f1857236e"&gt;an array of hooks&lt;/a&gt;.Whatever, the above naive implementation captures the essence of React Hooks.&lt;/p&gt;

&lt;h2&gt;
  
  
  JSX
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;button&amp;gt;Hello {name}!&amp;lt;/button&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;Hello name="World" /&amp;gt;&lt;/code&gt; are JSX,an extension to JavaScript, or a DSL to express DOM elements.TypeScript has excellent support for JSX. Thus JSX can be considered as typed HTML template expressions.&lt;/p&gt;

&lt;p&gt;Component names such as &lt;code&gt;Hello&lt;/code&gt; begin with an uppercase letter,while intrinsic HTML elements such as &lt;code&gt;button&lt;/code&gt; begin with a lowercase letter.Certain attributes in HTML are renamed to resolve conflicts with TypeScript keywords.For example, the &lt;code&gt;class&lt;/code&gt; attributes are renamed to &lt;code&gt;className&lt;/code&gt; in JSX.&lt;/p&gt;

&lt;p&gt;A component cannot directly return multiple elements.To return multiple elements, nest them inside a &lt;code&gt;div&lt;/code&gt; element, then return that &lt;code&gt;div&lt;/code&gt;.Sometimes returning an div element is not possible.For example, nesting multiple &lt;code&gt;&amp;lt;td&amp;gt;&lt;/code&gt; elements in &lt;code&gt;div&lt;/code&gt; results in invalid HTML.And sometimes, you just do not want to wrap them inside a &lt;code&gt;div&lt;/code&gt; element.Under such conditions, you can wrap them inside a &lt;code&gt;&amp;lt;React.Fragment&amp;gt;&lt;/code&gt;,which can be considered as a seamless div element.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;React.Fragment&amp;gt;&lt;/code&gt; accepts an optional &lt;code&gt;key&lt;/code&gt; attribute,which is its only acceptable attribute.For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// type annotations omitted for brevity
function Glossary({ items }) {
  return (
    &amp;lt;dl&amp;gt;
      {items.map(item =&amp;gt; (
        &amp;lt;React.Fragment key={item.id}&amp;gt;
          &amp;lt;dt&amp;gt;{item.term}&amp;lt;/dt&amp;gt;
          &amp;lt;dd&amp;gt;{item.description}&amp;lt;/dt&amp;gt;
        &amp;lt;/React.Fragment&amp;gt;
      ))}
    &amp;lt;/dl&amp;gt;
  )
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;key&lt;/code&gt; is a special attribute for React to identify member element in a list.It helps React to detect which members have changed, added, or removed.&lt;/p&gt;

&lt;p&gt;JSX is syntax sugar for calling &lt;code&gt;React.createElement&lt;/code&gt;,for example, &lt;code&gt;&amp;lt;Hello name="World" /&amp;gt;&lt;/code&gt; is equivalent to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;React.createElement(Hello, { name: "World" });

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So JSX is optional, you can use React without JSX.&lt;/p&gt;

&lt;h2&gt;
  
  
  Styling
&lt;/h2&gt;

&lt;p&gt;React does not have an opinion about how styles are defined.You can define styles in separate &lt;code&gt;*.css&lt;/code&gt; files.However, I prefer to define styles in TypeScript than CSS.You can check &lt;a href="https://michelebertoli.github.io/css-in-js/"&gt;this comparison of CSS-in-JS&lt;/a&gt;.Again, there are a lot of choices.&lt;/p&gt;

&lt;p&gt;Among those projects, I checked the five projects written in TypeScript:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/jsxstyle/jsxstyle"&gt;jsxstyle&lt;/a&gt; and &lt;a href="https://github.com/blakeembrey/react-free-style"&gt;react-free-style&lt;/a&gt; are inline style systems. I do not like inline style systems.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/streamich/freestyler"&gt;freestyler&lt;/a&gt;’s APIs are complex. There are too many choices.&lt;/li&gt;
&lt;li&gt;Both &lt;a href="https://stylable.io/"&gt;stylable&lt;/a&gt; and &lt;a href="https://typestyle.github.io/"&gt;typestyle&lt;/a&gt; provide a type safe styling language.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;stylable has a syntax similar to CSS, while typestyle just uses object literals (no custom AST transform).As I said before, I want to define styles &lt;em&gt;in TypeScript&lt;/em&gt;, thus I pick typestyle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Alternative Implementations
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://preactjs.com/"&gt;Preact&lt;/a&gt; is the most popular alternative implementation.It is small (3KB gzipped) and fast.However, to leverage many React libraries, &lt;code&gt;preact/compat&lt;/code&gt; is required.This compatibility layer is slow.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://infernojs.org/"&gt;Inferno&lt;/a&gt; is a faster alternative implementation.Unlike Preact, it is not that obsessed about the size (but still small).Like Preact, its compatibility layer &lt;code&gt;inferno-compat&lt;/code&gt; has extra overhead.Also, hooks is &lt;a href="https://github.com/infernojs/inferno/issues/1453"&gt;not supported yet&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://github.com/NervJS/nerv"&gt;Nerv&lt;/a&gt; is yet another small alternative implementation.It features compatibility with IE 8 and a more identical React API.Thus there is no &lt;code&gt;nerv-compat&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://twitter.com/chrisachard/status/1175022111758442497"&gt;Learn React in 10 tweets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.netlify.com/blog/2019/03/11/deep-dive-how-do-react-hooks-really-work/"&gt;Deep dive: How do React hooks really work?&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>RarCrack</title>
      <dc:creator>Jang Rush</dc:creator>
      <pubDate>Sun, 24 May 2020 15:31:39 +0000</pubDate>
      <link>https://dev.to/weakish/rarcrack-5e2i</link>
      <guid>https://dev.to/weakish/rarcrack-5e2i</guid>
      <description>&lt;p&gt;This note is written for RarCrack 0.2.&lt;/p&gt;

&lt;p&gt;RarCrack brute forces password for encrypted zip, rar, 7z files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rarcrack FILE_NAME --threads 4

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note that if &lt;code&gt;--threads&lt;/code&gt; is omitted, RarCrack will use 2 threads, no matter how many cores your CPU has.&lt;/p&gt;

&lt;p&gt;You can cancel the brute forcing (e.g. via &lt;code&gt;Ctrl-c&lt;/code&gt;) at any time,and RarCrack will resume cracking at next startup.This is because RarCrack uses a status file &lt;code&gt;FILE_NAME.xml&lt;/code&gt; at the same directory to record progress.&lt;/p&gt;

&lt;p&gt;And this mechanism can be used to speed up cracking.For example, if you remember that the password is 6 digits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;rarcrack&amp;gt;
  &amp;lt;abc&amp;gt;0123456789&amp;lt;/abc&amp;gt;
  &amp;lt;current&amp;gt;000000&amp;lt;/current&amp;gt;
  &amp;lt;good_password/&amp;gt;
&amp;lt;/rarcrack&amp;gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For zip and 7z files, an alternative to RarCrack is fcrackzip.And it has more features, e.g. specifying password range and using a dictionary.However, last time I tried to fcrackzip a zip file,it reported that the zip file is corrupt.And RarCrack successfully cracks the very zip file.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>A Basic Guide for New Marionettists</title>
      <dc:creator>Jang Rush</dc:creator>
      <pubDate>Sun, 24 May 2020 15:31:07 +0000</pubDate>
      <link>https://dev.to/weakish/a-basic-guide-for-new-marionettists-10fc</link>
      <guid>https://dev.to/weakish/a-basic-guide-for-new-marionettists-10fc</guid>
      <description>&lt;h2&gt;
  
  
  TLDR
&lt;/h2&gt;

&lt;p&gt;This article only covers the so-called masterless mode, a.k.a. &lt;code&gt;puppet apply&lt;/code&gt;,because the &lt;a href="https://puppet.com/docs/puppet/6.7/architecture.html"&gt;master-slave mode&lt;/a&gt; is &lt;a href="https://bugs.python.org/issue34605"&gt;unethical&lt;/a&gt; and &lt;a href="https://puppet.com/products/bolt"&gt;bolt&lt;/a&gt; sounds violent. On the other hand, &lt;code&gt;puppet apply&lt;/code&gt; plays the role of both master and slave, which is considered not unlikely inoffensive.&lt;/p&gt;

&lt;p&gt;Puppet uses a declarative DSL, i.e. describing the state of puppets. Below is an example from &lt;a href="https://puppet.com/docs/puppet/6.7/intro_puppet_language_and_code.html"&gt;the official document&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case $operatingsystem {
  centos, redhat: { $service_name = 'ntpd' }
  debian, ubuntu: { $service_name = 'ntp' }
}

package { 'ntp':
  ensure =&amp;gt; installed,
}

service { 'ntp':
  name =&amp;gt; $service_name,
  ensure =&amp;gt; running,
  enable =&amp;gt; true,
  subscribe =&amp;gt; File['ntp.conf'],
}

file { 'ntp.conf':
  path =&amp;gt; '/etc/ntp.conf',
  ensure =&amp;gt; file,
  require =&amp;gt; Package['ntp'],
  source =&amp;gt; "puppet:///modules/ntp/ntp.conf",
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This guide applies to Puppet 6.7.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;

&lt;p&gt;Install the &lt;code&gt;puppet-agent&lt;/code&gt; package (which provides &lt;code&gt;puppet apply&lt;/code&gt;),following the &lt;a href="https://puppet.com/docs/puppet/6.7/install_agents.html"&gt;instructions at official document&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As an oversimplified example, I wrote a script to ensure git is installed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# filename: laptop.pp
package {'git':
  ensure =&amp;gt; installed
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Validate its syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;puppet parser validate laptop.pp

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In practice, this is mainly for CI,since a decent editor should have warned you if you made some syntax mistakes.&lt;/p&gt;

&lt;p&gt;Rehearse the play (dry run):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;puppet apply --noop laptop.pp

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It’s show time: (run as root since installing package usually requires root permission)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;puppet apply laptop.pp

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can also pass a directory instead of a file to &lt;code&gt;puppet apply&lt;/code&gt;.But in this case Puppet combines all files under that directory as one script,without isolated scope.Thus I prefer use one file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Puppet DSL
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Style
&lt;/h3&gt;

&lt;p&gt;The Puppet community prefers &lt;code&gt;snake_case&lt;/code&gt; and two spaces soft tab.&lt;/p&gt;

&lt;h3&gt;
  
  
  Selector Expression
&lt;/h3&gt;

&lt;p&gt;Selector expression returns a value.For example, the case “statement” in the beginning code sample:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case $operatingsystem {
  centos, redhat: { $service_name = 'ntpd' }
  debian, ubuntu: { $service_name = 'ntp' }
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;can be rewritten as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$service_name = $operatingsystem ? {
  centos, redhat =&amp;gt; 'ntpd',
  debian, ubuntu =&amp;gt; 'ntp',
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Strictly speaking, they are not semantically equivalent.If the os failed to match, the former will do nothing,while the later will refuse to compile.&lt;/p&gt;

&lt;p&gt;However, the &lt;code&gt;if&lt;/code&gt; and &lt;code&gt;case&lt;/code&gt; “statements” are actually expressions,returning the value of the last expression in the executed blockor &lt;code&gt;undef&lt;/code&gt; when no block was executed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Puppet Defaults
&lt;/h3&gt;

&lt;p&gt;Puppet DSL has a wired syntax (capitalizing type name) for declaring defaults for a specific type of puppet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Set default values for the path attribute of the exec puppet.
Exec {
  path =&amp;gt; '/usr/bin:/bin:/usr/sbin:/sbin',
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The more wired part is, puppet defaults are &lt;strong&gt;dynamically scoped&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;Therefore, using per-expression defaults is preferred.Below is an example from &lt;a href="https://puppet.com/docs/puppet/6.7/lang_resources.html#resource-declaration-default-attributes"&gt;the official document&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;file {
  default:
    ensure =&amp;gt; file,
    owner =&amp;gt; "root",
    group =&amp;gt; "wheel",
    mode =&amp;gt; "0600",
  ;
  ['ssh_host_dsa_key', 'ssh_host_key', 'ssh_host_rsa_key']:
    # use all defaults
  ;
  ['ssh_config', 'ssh_host_dsa_key.pub', 'ssh_host_key.pub', 'ssh_host_rsa_key.pub', 'sshd_config']:
    # override mode
    mode =&amp;gt; "0644",
  ;
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Puppet Collector
&lt;/h3&gt;

&lt;p&gt;This is sometimes called the “spaceship operator”,which selects a group of puppets via attribute searching:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User &amp;lt;| groups == 'wheel' |&amp;gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Besides &lt;code&gt;==&lt;/code&gt;, there are other operators, &lt;code&gt;!=&lt;/code&gt;, &lt;code&gt;and&lt;/code&gt;, and &lt;code&gt;or&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lazy Puppet
&lt;/h3&gt;

&lt;p&gt;The at (&lt;code&gt;@&lt;/code&gt;) prefix marks a puppet declaration as lazy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@user {'ubuntu':
  uid =&amp;gt; 1000,
  comment =&amp;gt; 'default user',
  group =&amp;gt; wheel,
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Lazy puppets will not be applied until:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;explicitly realized, e.g. &lt;code&gt;realize User['ubuntu']&lt;/code&gt;, or&lt;/li&gt;
&lt;li&gt;implicitly realized by a matched collector, e.g. &lt;code&gt;User &amp;lt;| group == wheel |&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Glossary
&lt;/h2&gt;

&lt;p&gt;This guide uses different terms to the official Puppet documentation.These are just my personal preference.For example, the &lt;em&gt;script&lt;/em&gt; term used in this guide is called &lt;strong&gt;manifest&lt;/strong&gt; in the official Puppet documentation.In my opinion, &lt;em&gt;script&lt;/em&gt; makes more sense than &lt;strong&gt;manifest&lt;/strong&gt;.In fact, &lt;a href="https://www.chef.io/"&gt;chef&lt;/a&gt; refers to the similar notation as &lt;a href="https://docs.chef.io/recipes.html"&gt;recipe&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;agent&lt;/strong&gt; Puppet actually uses the term agent instead of &lt;em&gt;slave&lt;/em&gt;, but this is just a euphemism.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;catalog&lt;/strong&gt; In master &lt;em&gt;slave&lt;/em&gt; mode, catalog are compiled by master with &lt;em&gt;stage&lt;/em&gt; specific information. In &lt;code&gt;puppet apply&lt;/code&gt; mode, it is just unimportant mid-product.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;class&lt;/strong&gt; A &lt;em&gt;set&lt;/em&gt; of puppets. And a &lt;strong&gt;subclass&lt;/strong&gt; is &lt;em&gt;an extended set&lt;/em&gt; of puppets base on another &lt;em&gt;set&lt;/em&gt; of puppets, a.k.a. a class &lt;code&gt;inherits&lt;/code&gt; another class.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;environment&lt;/strong&gt; A &lt;em&gt;play&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fact&lt;/strong&gt; A &lt;em&gt;detail&lt;/em&gt; about the &lt;em&gt;stage&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Facter&lt;/strong&gt; The &lt;em&gt;stage manager&lt;/em&gt; can tell you &lt;em&gt;details&lt;/em&gt; about the &lt;em&gt;stage&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;filebucket&lt;/strong&gt; A repository for file backups.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hiera&lt;/strong&gt; A built-in key-value database for puppet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;lambda&lt;/strong&gt; In Puppet, a lambda can only be used in function calls. That is, it can only be passed to functions, but cannot be assigned to variables. To some extent, it is more like Ruby’s block.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;manifest&lt;/strong&gt; The &lt;em&gt;script&lt;/em&gt; used by a marionettist. Puppet refers to the entry point as &lt;strong&gt;main manifest&lt;/strong&gt; or &lt;strong&gt;site manifest&lt;/strong&gt;. &lt;code&gt;puppet apply&lt;/code&gt; only cares about the &lt;em&gt;script&lt;/em&gt; passed to it on the command line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;node&lt;/strong&gt; The &lt;em&gt;stage&lt;/em&gt; for the show. In &lt;code&gt;puppet apply&lt;/code&gt; mode, the local machine is the only &lt;em&gt;stage&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;resource&lt;/strong&gt; A &lt;em&gt;puppet&lt;/em&gt; controlled by the marionettist. Puppet uses the term &lt;strong&gt;virtual resource&lt;/strong&gt; to refer to &lt;em&gt;lazy puppet&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Tinygo</title>
      <dc:creator>Jang Rush</dc:creator>
      <pubDate>Sun, 24 May 2020 15:30:52 +0000</pubDate>
      <link>https://dev.to/weakish/tinygo-4eof</link>
      <guid>https://dev.to/weakish/tinygo-4eof</guid>
      <description>&lt;p&gt;&lt;a href="https://tinygo.org"&gt;Tinygo&lt;/a&gt; is a Go compiler for microcontrollers and WebAssembly.It also supports x86 32 bit and 64 bit Linux.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install llvm-7-dev libclang-7-dev
go get -u github.com/tinygo-org/tinygo

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Usage
&lt;/h3&gt;

&lt;p&gt;To compile a Linux executable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tinygo build -o hello_tiny hello.go

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The output size of a hello world program is very impressive to me:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.1M hello
12K hello_tiny

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Or run it directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tinygo run hello.go

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Go Language Features
&lt;/h2&gt;

&lt;p&gt;Not supported:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maps.&lt;/li&gt;
&lt;li&gt;Concurrency.&lt;/li&gt;
&lt;li&gt;Reflection.&lt;/li&gt;
&lt;li&gt;Cgo.&lt;/li&gt;
&lt;li&gt;Many parts of standard library (due to the above missing pieces).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;recover()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;complex64&lt;/code&gt;, &lt;code&gt;complex128&lt;/code&gt;, and arithmetic on complex numbers.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;defer&lt;/code&gt; a call on a function pointer.&lt;/li&gt;
&lt;li&gt;3-index slicing, e.g. &lt;code&gt;slice = array[2:4:7]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Dive into Rust</title>
      <dc:creator>Jang Rush</dc:creator>
      <pubDate>Sun, 24 May 2020 15:30:23 +0000</pubDate>
      <link>https://dev.to/weakish/dive-into-rust-4e7n</link>
      <guid>https://dev.to/weakish/dive-into-rust-4e7n</guid>
      <description>&lt;h2&gt;
  
  
  Variable Shadowing
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let mut guess = String::new();

io::stdin().read_line(&amp;amp;mut guess)
    .expect("Failed to read line");

let guess: u32 = guess.trim().parse()
    .expect("Please type a number!");

const CONSTANT: &amp;amp;str = "a constant expression, not the result of a function call computed at runtime";
let immutable_variable: &amp;amp;str = "variables are immutable by default";
let mut mutable_variable: u32 = 0;
let immutable_variable: &amp;amp;str = "shadowing the previous immutable_variable, which is bad";
let immutable_variable: u32 = 1;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Data Types
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scalar Types
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Integer: &lt;code&gt;i8&lt;/code&gt;, &lt;code&gt;i16&lt;/code&gt;, &lt;code&gt;i32&lt;/code&gt;, &lt;code&gt;i64&lt;/code&gt;, &lt;code&gt;i128&lt;/code&gt;, &lt;code&gt;isize&lt;/code&gt; and their unsigned counterpart &lt;code&gt;u8&lt;/code&gt;, …, &lt;code&gt;usize&lt;/code&gt;. &lt;code&gt;isize&lt;/code&gt; is &lt;code&gt;i32&lt;/code&gt; on 32 bit systems and &lt;code&gt;i64&lt;/code&gt; on 64 bit systems. Integer types default to &lt;code&gt;i32&lt;/code&gt;. Compiling in debug mode will check for integer overflows. Relying on integer overflow’s wrapping behavior is considered an error, use the &lt;code&gt;Wrapping&lt;/code&gt; type instead.&lt;/li&gt;
&lt;li&gt;Floats: &lt;code&gt;f32&lt;/code&gt; and &lt;code&gt;f64&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Boolean: &lt;code&gt;bool&lt;/code&gt; (values: &lt;code&gt;true&lt;/code&gt; and &lt;code&gt;false&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Character: &lt;code&gt;char&lt;/code&gt; (Unicode Scalar Value).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Compound Types
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Tuple: tuple index must be written as a decimal literal, e.g. &lt;code&gt;(0, 1, 2).1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Array: can be considered as a tuple whose elements all have the same type. Index out of bounds is a &lt;em&gt;runtime&lt;/em&gt; error though.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Control Flow
&lt;/h2&gt;

&lt;p&gt;Condition &lt;em&gt;must&lt;/em&gt; be a &lt;code&gt;bool&lt;/code&gt;.Nice!&lt;/p&gt;

&lt;h2&gt;
  
  
  Enum
&lt;/h2&gt;

&lt;p&gt;Rust’s enum is actually a tagged union.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generics
&lt;/h2&gt;

&lt;p&gt;Rust monomorphizes code that is using generics at compile time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Traits
&lt;/h2&gt;

&lt;p&gt;Rust’s traits is similar to interface in other languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory Management
&lt;/h2&gt;

&lt;p&gt;Rust does not use GC or RC.For values on the heap, it only allow one variable “own” a value at a time.Assignment, passing a value to function and returning a value move the “ownership”.Also, Rust allows multiple immutable pointers (&lt;code&gt;&amp;amp;&lt;/code&gt;) but only one mutable pointer (&lt;code&gt;&amp;amp;mut&lt;/code&gt;),and restricts mixing immutable and mutable pointers to the same target.The basic idea is to keep the number of reference to a value to one,to make memory management easier for the compiler.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let s1 = String::from("A long long string");
let s2 = s1 + ".";

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Conceptually s2 can be considered as a newly constructed immutable variable,but since the ownership moves from s1 to s2, and s1 becomes invalid afterwards,the compiler just need to appends &lt;code&gt;"."&lt;/code&gt; to the end of the value, which is efficient.&lt;/p&gt;

&lt;p&gt;Smart pointers can be used for reference counting.Smart pointers are structs satisfying &lt;code&gt;Deref&lt;/code&gt; and &lt;code&gt;Drop&lt;/code&gt; traits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enum List {
    Cons(i32, Box&amp;lt;List&amp;gt;),
    Nil,
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the above example, &lt;code&gt;Box&amp;lt;List&amp;gt;&lt;/code&gt; is a smart pointer.We use &lt;code&gt;Box&amp;lt;List&amp;gt;&lt;/code&gt; to store the &lt;code&gt;Box&amp;lt;List&amp;gt;&lt;/code&gt; data on the heap,otherwise &lt;code&gt;Cons(i32, List)&lt;/code&gt; will result in infinite size on the stack,which causes Rust failed to construct the &lt;code&gt;List&lt;/code&gt; enum.&lt;/p&gt;

&lt;p&gt;To allow &lt;code&gt;cons&lt;/code&gt; more than one lists from a same base list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enum List {
    Cons(i32, Rc&amp;lt;List&amp;gt;),
    Nil,
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Rc&lt;/code&gt; is another smart pointer for reference counting.It increases the reference counter on &lt;code&gt;RC::clone(&amp;amp;l)&lt;/code&gt;,and reduce the reference counter automatically when the related variable goes out of scope.When there are zero references, the value will be cleaned up.&lt;/p&gt;

&lt;p&gt;Be aware that &lt;code&gt;Rc&lt;/code&gt; only works in single-thread context.In multiple-threads context, use &lt;code&gt;Arc&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;In Rust, functions and struts working with references need lifetime annotation.However, Rust can infer function lifetime in simplest cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If there is only one reference input parameter, then its lifetime will be the lifetime of output values.&lt;/li&gt;
&lt;li&gt;If there are multiple reference input parameters, but one of them is &lt;code&gt;&amp;amp;self&lt;/code&gt; or &lt;code&gt;&amp;amp;mut self&lt;/code&gt;, then its lifetime will be the lifetime of output values.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;String literals have a &lt;code&gt;'static&lt;/code&gt; lifetime, which lives for the entire duration of the program.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let b;
{
    let a = "hi";
    b = a;
}
println!("{}", b); // prints "hi"

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Lifetime annotation tells Rust compiler the lifetime of variables,but it cannot alter the lifetime.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;While Go use special function name &lt;code&gt;TestXxx&lt;/code&gt;, Rust uses &lt;code&gt;#[test]&lt;/code&gt; attribute annotation.&lt;/p&gt;

&lt;p&gt;Unit tests are written in &lt;code&gt;mod tests&lt;/code&gt;, and integration tests are put in the &lt;code&gt;test&lt;/code&gt; directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation Comments
&lt;/h2&gt;

&lt;p&gt;Three leading slashes &lt;code&gt;///&lt;/code&gt; with Markdown.&lt;/p&gt;

&lt;p&gt;Similar to Python, Rust also supports doctest:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/// # Example
///
/// ```


/// let foo = "foo";
/// assert_eq!(foo, "foo");
///

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


## unsafe

In the unsafe block (`unsafe {}`), you can:

- 

Dereference a raw pointer which

  - can have both immutable and mutable pointers or multiple mutable pointers to the same location;
  - is not guaranteed to point to valid memory;
  - can be null;
  - does not implement any automatic cleanup.
- 

Call an unsafe function or method (`unsafe fn dangerous() {}`, including foreign functions such as C functions).

- 

Access or modify a mutable static variable (Rust call global variables as static variables).

- 

Implement an unsafe trait.

- 

Access fields of an union (the unsafe counterpart of Rust’s `enum`, mainly used for FFI).
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

</description>
    </item>
    <item>
      <title>JupyterLab Guide</title>
      <dc:creator>Jang Rush</dc:creator>
      <pubDate>Sun, 24 May 2020 15:30:14 +0000</pubDate>
      <link>https://dev.to/weakish/jupyterlab-guide-nhl</link>
      <guid>https://dev.to/weakish/jupyterlab-guide-nhl</guid>
      <description>&lt;p&gt;JupyterLab is the next generation UI of Jupyter Notebook (formly known as IPython Notebook).&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;JupyterLab can be installed via &lt;code&gt;conda&lt;/code&gt;, &lt;code&gt;pip&lt;/code&gt;, and &lt;code&gt;pipenv&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, to install with &lt;code&gt;conda&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;conda install -c conda-forge jupyterlab

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once installed, you can start it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jupyter lab

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To shutdown JupyterLab, first shutdown all kernels while &lt;code&gt;Kernel&lt;/code&gt; menu,then type &lt;code&gt;ctrl-c&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Notebooks
&lt;/h2&gt;

&lt;p&gt;Jupyter notebooks combines:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;live runnable code cells&lt;/li&gt;
&lt;li&gt;text cells (Markdown, LaTeX equations, images, interactive visualizations)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Multiple view(tabs) can be opened for the same notebook,with synced content.&lt;/p&gt;

&lt;p&gt;The blue collapser button on left of each cell can trigger collapsing and expanding cells.&lt;/p&gt;

&lt;p&gt;Right-click on a notebook and select “New Console for Notebook” can attach to the notebook kernel.This provides a log of all computations done in the kernel (in the order in the order in which they were done),and a place to interactively inspect kernel state without changing the notebook.&lt;/p&gt;

&lt;h3&gt;
  
  
  Raw HTML
&lt;/h3&gt;

&lt;p&gt;IPython kernel provides a variety of convenience classes for displaying rich output, including HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from IPython.display import display, HTML
display(HTML('&amp;lt;del&amp;gt;Hello World&amp;lt;/del&amp;gt;'))

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;del&gt;Hello World&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from IPython.display import display
display({'text/html': '&amp;lt;del&amp;gt;Hello World&amp;lt;/del&amp;gt;'}, raw=True)

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;del&gt;Hello World&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;MIME types supported by default:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;document: &lt;code&gt;text/markdown&lt;/code&gt;, &lt;code&gt;text/html&lt;/code&gt;, &lt;code&gt;text/latex&lt;/code&gt;, &lt;code&gt;application/vdom.v1+json&lt;/code&gt; (Virtual DOM)&lt;/li&gt;
&lt;li&gt;images: &lt;code&gt;image/bmp&lt;/code&gt;, &lt;code&gt;image/gif&lt;/code&gt;, &lt;code&gt;image/jpeg&lt;/code&gt;, &lt;code&gt;image/png&lt;/code&gt;, &lt;code&gt;image/svg+xml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;data: &lt;code&gt;application/json&lt;/code&gt;, &lt;code&gt;application/vnd.vega.v2+json&lt;/code&gt;, &lt;code&gt;application/vnd.vegalite.v1+json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;other: CSV (as &lt;code&gt;.csv&lt;/code&gt; files, no MIME type), PDF (as &lt;code&gt;.pdf&lt;/code&gt; files, with &lt;code&gt;application/pdf&lt;/code&gt; MIME type, view only)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other Jupyter kernels offer similar APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keymap
&lt;/h2&gt;

&lt;p&gt;Keyboard shortcuts can be viewed in menu, context menu, and command palette (Commands tab of sidebar).&lt;/p&gt;

&lt;p&gt;Keyboard shortcut for command palette: &lt;code&gt;Ctrl+Shift+c&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Code Cell/Console
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Tab&lt;/code&gt;: complete.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Shift+Tab&lt;/code&gt;: tooltip.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Shift+Enter&lt;/code&gt;: run code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Image File Viewer
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;+&lt;/code&gt; and &lt;code&gt;-&lt;/code&gt;: zoom&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[&lt;/code&gt; and &lt;code&gt;]&lt;/code&gt;: rotate&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;H&lt;/code&gt; and &lt;code&gt;V&lt;/code&gt;: flip horizontally/vertically&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;I&lt;/code&gt;: invert the colors&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0&lt;/code&gt;: reset&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Mouse
&lt;/h3&gt;

&lt;p&gt;Besides keyboard, mouse is also useful.Drag and drop cells within one notebook to rearrange them;drag and drop cells within notebooks to copy content;drag and drop tabs to arrange their layout.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extensions
&lt;/h2&gt;

&lt;p&gt;JupyterLab extensions are npm packages.&lt;/p&gt;

&lt;p&gt;To install extensions, first install nodejs.For example, via &lt;code&gt;conda&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;conda install -c conda-forge nodejs

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then use &lt;code&gt;jupyter labextension&lt;/code&gt; to manage extensions,via invoking subcommands like &lt;code&gt;list&lt;/code&gt;, &lt;code&gt;install&lt;/code&gt;/&lt;code&gt;uninstall&lt;/code&gt;, &lt;code&gt;enable&lt;/code&gt;/&lt;code&gt;unable&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools and Services
&lt;/h2&gt;

&lt;h3&gt;
  
  
  nbdime
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/jupyter/nbdime"&gt;nbdime&lt;/a&gt; provides tools for diffing and merging of &lt;a href="https://jupyter-notebook.readthedocs.io"&gt;Jupyter Notebooks&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;nbdiff&lt;/code&gt; compare notebooks in a terminal-friendly way&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nbmerge&lt;/code&gt; three-way merge of notebooks with automatic conflict resolution&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nbdiff-web&lt;/code&gt; shows you a rich rendered diff of notebooks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nbmerge-web&lt;/code&gt; gives you a web-based three-way merge tool for notebooks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nbshow&lt;/code&gt; present a single notebook in a terminal-friendly way&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  nbconvert
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://nbconvert.readthedocs.io"&gt;nbconvert&lt;/a&gt; allows you to convert a Jupyter .ipynb notebook document file into another static format including HTML, LaTeX, PDF, Markdown, reStructuredText, and more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nbviewer.jupyter.org"&gt;nbviewer&lt;/a&gt; is a free web service based on &lt;code&gt;nbconvert&lt;/code&gt; to share static html versions of notebook files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Binder
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://mybinder.org"&gt;Binder&lt;/a&gt; is a free web service to turn a GitHub repo into a collection of interactive notebooks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enter a url to a GitHub repo of Jupyter notebooks.&lt;/li&gt;
&lt;li&gt;Binder builds a Docker image for the repository, based on &lt;code&gt;requirements.txt&lt;/code&gt; or &lt;code&gt;environment.yml&lt;/code&gt; in repository’s root directory.&lt;/li&gt;
&lt;li&gt;Binder launches a JupyterHub server. It provides a reusable/shareable link to live repository.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;This guide itself is authored in JupyterLab.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
