<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Turtle</title>
    <link>https://glubbdubdrib.com/</link>
    <description>Turtle blogging</description>
    <language>en</language>
    <managingEditor>turtle (https://glubbdubdrib.com/)</managingEditor>
    <webMaster>turtle (https://glubbdubdrib.com/)</webMaster>
    <lastBuildDate>Sat, 10 Jan 2026 02:57:10 +0000</lastBuildDate>
    <atom:link href="https://glubbdubdrib.com/feed.xml" rel="self" type="application/rss+xml"/>
    
    <item>
      <title>ERC20 Token &amp; Faucet Deployer</title>
      
      
      <link>https://glubbdubdrib.com/erc20-token-faucet/</link>
      <guid isPermaLink="true">https://glubbdubdrib.com/erc20-token-faucet/</guid>
      <pubDate>Fri, 09 Jan 2026 00:00:00 +0000</pubDate>
      <description><![CDATA[<p>In this post, we'll explore how ERC20 tokens on Ethereum work and how to set them up.</p>
<h1>ERC20 Tokens</h1>
<p>ERC20 tokens are contracts on Ethereum adhering to a simple interface:</p>
<pre class="language-solidity"><code class="language-solidity"><span class="token keyword">interface</span> <span class="token class-name">IERC20</span> <span class="token punctuation">{</span>
    <span class="token keyword">function</span> <span class="token function">totalSupply</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">external</span> <span class="token keyword">view</span> <span class="token keyword">returns</span> <span class="token punctuation">(</span><span class="token builtin">uint256</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">function</span> <span class="token function">balanceOf</span><span class="token punctuation">(</span><span class="token builtin">address</span> account<span class="token punctuation">)</span> <span class="token keyword">external</span> <span class="token keyword">view</span> <span class="token keyword">returns</span> <span class="token punctuation">(</span><span class="token builtin">uint256</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">function</span> <span class="token function">transfer</span><span class="token punctuation">(</span><span class="token builtin">address</span> to<span class="token punctuation">,</span> <span class="token builtin">uint256</span> amount<span class="token punctuation">)</span> <span class="token keyword">external</span> <span class="token keyword">returns</span> <span class="token punctuation">(</span><span class="token builtin">bool</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">function</span> <span class="token function">allowance</span><span class="token punctuation">(</span><span class="token builtin">address</span> owner<span class="token punctuation">,</span> <span class="token builtin">address</span> spender<span class="token punctuation">)</span> <span class="token keyword">external</span> <span class="token keyword">view</span> <span class="token keyword">returns</span> <span class="token punctuation">(</span><span class="token builtin">uint256</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">function</span> <span class="token function">approve</span><span class="token punctuation">(</span><span class="token builtin">address</span> spender<span class="token punctuation">,</span> <span class="token builtin">uint256</span> amount<span class="token punctuation">)</span> <span class="token keyword">external</span> <span class="token keyword">returns</span> <span class="token punctuation">(</span><span class="token builtin">bool</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">function</span> <span class="token function">transferFrom</span><span class="token punctuation">(</span><span class="token builtin">address</span> <span class="token keyword">from</span><span class="token punctuation">,</span> <span class="token builtin">address</span> to<span class="token punctuation">,</span> <span class="token builtin">uint256</span> amount<span class="token punctuation">)</span> <span class="token keyword">external</span> <span class="token keyword">returns</span> <span class="token punctuation">(</span><span class="token builtin">bool</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">event</span> <span class="token function">Transfer</span><span class="token punctuation">(</span><span class="token builtin">address</span> <span class="token keyword">indexed</span> <span class="token keyword">from</span><span class="token punctuation">,</span> <span class="token builtin">address</span> <span class="token keyword">indexed</span> to<span class="token punctuation">,</span> <span class="token builtin">uint256</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">event</span> <span class="token function">Approval</span><span class="token punctuation">(</span><span class="token builtin">address</span> <span class="token keyword">indexed</span> owner<span class="token punctuation">,</span> <span class="token builtin">address</span> <span class="token keyword">indexed</span> spender<span class="token punctuation">,</span> <span class="token builtin">uint256</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>The interface defines six core functions:</p>
<ul>
<li><code>totalSupply()</code>: Returns the total number of tokens in circulation</li>
<li><code>balanceOf()</code>: Returns the token balance for a given address</li>
<li><code>transfer()</code>: Moves tokens from the caller to a recipient</li>
<li><code>approve()</code>: Grants permission for another address to spend tokens on your behalf</li>
<li><code>allowance()</code>: Checks how many tokens a spender is authorized to use</li>
<li><code>transferFrom()</code>: Enables delegated transfers (used by DEXs and other protocols)</li>
</ul>
<p>To create a new token, we provide the name, symbol, and decimals in the constructor when deploying the contract:</p>
<pre class="language-solidity"><code class="language-solidity"><span class="token keyword">constructor</span><span class="token punctuation">(</span>
    <span class="token builtin">string</span> <span class="token keyword">memory</span> _name<span class="token punctuation">,</span>
    <span class="token builtin">string</span> <span class="token keyword">memory</span> _symbol<span class="token punctuation">,</span>
    <span class="token builtin">uint8</span> _decimals
<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></code></pre>
<p>The constructor only sets the token's metadata. To actually create tokens, you must call the <code>mint()</code> function after deployment to create tokens at a specific address.</p>
<h1>ERC20 Faucet</h1>
<p>Deploying tokens is useful, but sometimes you want a &quot;faucet&quot; for that token as well. A faucet is a contract that distributes tokens to users on demand, which is particularly useful on testnets where users need tokens to interact with dApps.</p>
<p>The <code>ERC20Faucet</code> contract extends the standard ERC20 contract with an additional method that allows any caller to request tokens:</p>
<pre class="language-solidity"><code class="language-solidity"><span class="token keyword">function</span> <span class="token function">money_pweese</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">public</span> <span class="token punctuation">{</span>
    <span class="token builtin">uint256</span> amount <span class="token operator">=</span> <span class="token number">5</span> <span class="token operator">*</span> <span class="token number">10</span> <span class="token operator">**</span> decimals<span class="token punctuation">;</span>
    <span class="token keyword">require</span><span class="token punctuation">(</span>_balances<span class="token punctuation">[</span><span class="token builtin">address</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token operator">>=</span> amount<span class="token punctuation">,</span> <span class="token string">"Insufficient faucet balance"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">_transfer</span><span class="token punctuation">(</span><span class="token builtin">address</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">,</span> msg<span class="token punctuation">.</span>sender<span class="token punctuation">,</span> amount<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>This function transfers 5 tokens (5 × 10^decimals) from the contract's own balance to the caller. Before users can claim tokens, the deployer must first mint tokens to the contract address using <code>mint(address(this), amount)</code>.</p>
<hr>
<p>Talking is a hydrant in the yard and writing is a faucet upstairs in the house. Opening the first takes the pressure off the second. - Robert Frost</p>
]]></description>
    </item>
    
    <item>
      <title>Key Generator Service with DynamoDB</title>
      
      
      <link>https://glubbdubdrib.com/dynamodb/</link>
      <guid isPermaLink="true">https://glubbdubdrib.com/dynamodb/</guid>
      <pubDate>Wed, 07 Aug 2024 00:00:00 +0000</pubDate>
      <description><![CDATA[<p>In this post, we'll explore how DynamoDB works by building a key generation service (KGS) using Go.</p>
<h3>Background</h3>
<p>A key generation service is useful for decoupling unique key creation from any other business logic.<br>
This service comes up in System Design questions such as <code>URL shortner</code> and <code>Pastebin</code>.<br>
It works by generating random base64 keys and storing them in an <code>available_keys</code> table.<br>
Once a key is requested to be used, that key is then moved to the <code>used_keys</code> table.</p>
<h3>Setup</h3>
<p>For our storage, we will use Amazon's DynamoDB, a NoSQL storage. To run it locally, type:</p>
<pre class="language-sh"><code class="language-sh"><span class="token function">docker</span> run <span class="token parameter variable">-p</span> <span class="token number">8000</span>:8000 amazon/dynamodb-local</code></pre>
<h3>Generating the keys</h3>
<p>To generate the keys, we'll use the <a href="https://pkg.go.dev/github.com/google/uuid">uuid</a> package to generate the random string and base64 encode it.</p>
<pre class="language-go"><code class="language-go"><span class="token keyword">import</span> <span class="token punctuation">(</span>
    <span class="token string">"encoding/base64"</span>

    <span class="token string">"github.com/google/uuid"</span>
<span class="token punctuation">)</span>

hash <span class="token operator">:=</span> uuid<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
encodedHash <span class="token operator">:=</span> base64<span class="token punctuation">.</span>StdEncoding<span class="token punctuation">.</span><span class="token function">EncodeToString</span><span class="token punctuation">(</span>hash<span class="token punctuation">[</span><span class="token punctuation">:</span><span class="token punctuation">]</span><span class="token punctuation">)</span></code></pre>
<h2>Saving keys into DynamoDB</h2>
<p><a href="https://en.wikipedia.org/wiki/Amazon_DynamoDB">DynamoDB</a> consists of tables, items and indices.<br>
Each table does not need a schema like in relational DBs but does require a primary key.<br>
This can be any unique attribute of the item. If two attributes are used, one will be the partition key and the other the sort key.</p>
<p>For our example, we will use the key as the primary key.</p>
<pre class="language-go"><code class="language-go">    <span class="token keyword">type</span> KeyItem <span class="token keyword">struct</span> <span class="token punctuation">{</span>
        Key       <span class="token builtin">string</span> <span class="token string">`dynamodbav:"key"`</span>
        CreatedAt <span class="token builtin">string</span>
        UpdatedAt <span class="token builtin">string</span>
    <span class="token punctuation">}</span>

now <span class="token operator">:=</span> time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">UTC</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

item <span class="token operator">:=</span> KeyItem<span class="token punctuation">{</span>
    Key<span class="token punctuation">:</span>       encodedHash<span class="token punctuation">,</span>
    CreatedAt<span class="token punctuation">:</span> now<span class="token punctuation">,</span>
    UpdatedAt<span class="token punctuation">:</span> now<span class="token punctuation">,</span>
<span class="token punctuation">}</span></code></pre>
<p>To create the tables and save the key in the <code>available_keys</code> table we will use the <a href="https://pkg.go.dev/github.com/aws/aws-sdk-go-V2">aws-sdk-go-V2</a> package.<br>
This package is the successor to the original AWS sdk. We assume that the client is already initialized and the <code>used_keys</code> table is created identically to the <code>available_keys</code> table.</p>
<pre class="language-go"><code class="language-go"><span class="token comment">// Create the table</span>
client<span class="token punctuation">.</span><span class="token function">CreateTable</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> <span class="token operator">&amp;</span>dynamodb<span class="token punctuation">.</span>CreateTableInput<span class="token punctuation">{</span>
        TableName<span class="token punctuation">:</span> aws<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>TableAvailableKeys<span class="token punctuation">)</span><span class="token punctuation">,</span>
        AttributeDefinitions<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>types<span class="token punctuation">.</span>AttributeDefinition<span class="token punctuation">{</span>
            <span class="token punctuation">{</span>
                AttributeName<span class="token punctuation">:</span> aws<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token string">"key"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                AttributeType<span class="token punctuation">:</span> types<span class="token punctuation">.</span>ScalarAttributeTypeS<span class="token punctuation">,</span>
            <span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span>
        KeySchema<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>types<span class="token punctuation">.</span>KeySchemaElement<span class="token punctuation">{</span>
            <span class="token punctuation">{</span>
                AttributeName<span class="token punctuation">:</span> aws<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token string">"key"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                KeyType<span class="token punctuation">:</span>       types<span class="token punctuation">.</span>KeyTypeHash<span class="token punctuation">,</span>
            <span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span>
        ProvisionedThroughput<span class="token punctuation">:</span> <span class="token operator">&amp;</span>types<span class="token punctuation">.</span>ProvisionedThroughput<span class="token punctuation">{</span>
            ReadCapacityUnits<span class="token punctuation">:</span>  aws<span class="token punctuation">.</span><span class="token function">Int64</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            WriteCapacityUnits<span class="token punctuation">:</span> aws<span class="token punctuation">.</span><span class="token function">Int64</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">)</span>
<span class="token comment">// Save the item</span>
marshalledItem<span class="token punctuation">,</span> err <span class="token operator">:=</span> attributevalue<span class="token punctuation">.</span><span class="token function">MarshalMap</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
    <span class="token function">panic</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>

name <span class="token operator">:=</span> <span class="token string">"available_keys"</span>
<span class="token boolean">_</span><span class="token punctuation">,</span> err <span class="token operator">=</span> client<span class="token punctuation">.</span><span class="token function">PutItem</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> <span class="token operator">&amp;</span>dynamodb<span class="token punctuation">.</span>PutItemInput<span class="token punctuation">{</span>
    Item<span class="token punctuation">:</span>      marshalledItem<span class="token punctuation">,</span>
    TableName<span class="token punctuation">:</span> <span class="token operator">&amp;</span>name<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
    <span class="token function">panic</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<p>As you can see, creating tables and adding items is pretty straight forward in DynamoDB.</p>
<h2>Accessing the keys</h2>
<p>When a key is requested from the service, we retrieve the first available key and move it to the <code>used_keys</code> table.<br>
This allows us to reuse keys when they are no longer needed.</p>
<p>First, scan the <code>available_keys</code> table for a key:</p>
<pre class="language-go"><code class="language-go"><span class="token keyword">var</span> limit <span class="token builtin">int32</span> <span class="token operator">=</span> <span class="token number">1</span>
res<span class="token punctuation">,</span> err <span class="token operator">:=</span> k<span class="token punctuation">.</span>client<span class="token punctuation">.</span><span class="token function">Scan</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> <span class="token operator">&amp;</span>dynamodb<span class="token punctuation">.</span>ScanInput<span class="token punctuation">{</span>
    TableName<span class="token punctuation">:</span> aws<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token string">"available_keys"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    Limit<span class="token punctuation">:</span>     <span class="token operator">&amp;</span>limit<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
    <span class="token function">panic</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<p>Next, save that key in the <code>used_keys</code> table:</p>
<pre class="language-go"><code class="language-go">item <span class="token operator">:=</span> tables<span class="token punctuation">.</span>KeyItem<span class="token punctuation">{</span><span class="token punctuation">}</span>
err <span class="token operator">=</span> attributevalue<span class="token punctuation">.</span><span class="token function">UnmarshalMap</span><span class="token punctuation">(</span>res<span class="token punctuation">.</span>Items<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>item<span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
    <span class="token function">panic</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>

item<span class="token punctuation">.</span>CreatedAt <span class="token operator">=</span> time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">UTC</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
item<span class="token punctuation">.</span>UpdatedAt <span class="token operator">=</span> item<span class="token punctuation">.</span>CreatedAt

marshalledItem<span class="token punctuation">,</span> err <span class="token operator">:=</span> attributevalue<span class="token punctuation">.</span><span class="token function">MarshalMap</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
    <span class="token function">panic</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token boolean">_</span><span class="token punctuation">,</span> err <span class="token operator">=</span> k<span class="token punctuation">.</span>client<span class="token punctuation">.</span><span class="token function">PutItem</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> <span class="token operator">&amp;</span>dynamodb<span class="token punctuation">.</span>PutItemInput<span class="token punctuation">{</span>
    Item<span class="token punctuation">:</span>      marshalledItem<span class="token punctuation">,</span>
    TableName<span class="token punctuation">:</span> aws<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token string">"used_keys"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
    <span class="token function">panic</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<p>Finally, delete the key from the <code>available_keys</code> table:</p>
<pre class="language-go"><code class="language-go">key<span class="token punctuation">,</span> err <span class="token operator">:=</span> attributevalue<span class="token punctuation">.</span><span class="token function">Marshal</span><span class="token punctuation">(</span>item<span class="token punctuation">.</span>Key<span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
    <span class="token function">panic</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token boolean">_</span><span class="token punctuation">,</span> err <span class="token operator">=</span> k<span class="token punctuation">.</span>client<span class="token punctuation">.</span><span class="token function">DeleteItem</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> <span class="token operator">&amp;</span>dynamodb<span class="token punctuation">.</span>DeleteItemInput<span class="token punctuation">{</span>
    Key<span class="token punctuation">:</span> <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span>types<span class="token punctuation">.</span>AttributeValue<span class="token punctuation">{</span>
        <span class="token string">"key"</span><span class="token punctuation">:</span> key<span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    TableName<span class="token punctuation">:</span> aws<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token string">"available_keys"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
    <span class="token function">panic</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<p>Note: deleting the key involves doing the inverse approach. We get the key from the <code>used_keys</code> table, delete it from there and add it back to the <code>available_keys</code> table.</p>
<hr>
<p>It's easy to play any musical instrument: all you have to do is touch the right key at the right time and the instrument will play itself. - Johann Sebastian Bach</p>
]]></description>
    </item>
    
    <item>
      <title>go:linkname for Gophers</title>
      
      
      <link>https://glubbdubdrib.com/golinkname/</link>
      <guid isPermaLink="true">https://glubbdubdrib.com/golinkname/</guid>
      <pubDate>Tue, 18 Jun 2024 00:00:00 +0000</pubDate>
      <description><![CDATA[<p>Go has a list of <a href="https://pkg.go.dev/cmd/compile#hdr-Compiler_Directives">compiler directives</a>.<br>
These <a href="https://en.wikipedia.org/wiki/Directive_(programming)">directives</a> specify how a compiler should process its output.<br>
They can also be used for non standard behaviors.<br>
These directives are added as comments above either methods or variables.<br>
They are similar to either the <a href="https://pkg.go.dev/go/build">build</a> or <a href="https://pkg.go.dev/embed">embed</a> tags.<br>
Note it is important to not leave any space between the <code>go</code> and the forward slashes, otherwise they won't be picked up by the compiler.</p>
<pre class="language-go"><code class="language-go"><span class="token comment">//go:build</span>
<span class="token comment">//go:embed</span>
<span class="token comment">//go:linkname</span></code></pre>
<h2>Why?</h2>
<p><code>go:linkname</code> can be used to access or override unexported methods.<br>
In general, it should be avoided since there is no guarantee that the behavior won't change in future Go versions.<br>
This is still a cool feature of Go, so let's explore it further.</p>
<h2>How?</h2>
<p>For this example, we'll be accessing the unexported method <code>open</code> in a separate package:</p>
<pre class="language-go"><code class="language-go"><span class="token keyword">package</span> door

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">"fmt"</span>
<span class="token punctuation">)</span>

<span class="token keyword">func</span> <span class="token function">open</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"Opening the door!"</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<p>Add an empty exportable method in your package.<br>
Remember to import the package containing your unexported method, otherwise it will fail to compile:</p>
<pre class="language-go"><code class="language-go"><span class="token keyword">package</span> open

<span class="token keyword">import</span> <span class="token boolean">_</span> <span class="token string">"example1/door"</span>

<span class="token keyword">func</span> <span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
<p>Next, add an empty assembly file <code>i.s</code> in the <code>open</code> package. If this is not added, you'll get a <code>missing function body</code> error.</p>
<p>Finally add the <code>go:linkname</code> directive to the unexported method. Remember to import the <code>unsafe</code> package as well:</p>
<pre class="language-go"><code class="language-go"><span class="token keyword">package</span> door

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">"fmt"</span>
	<span class="token boolean">_</span> <span class="token string">"unsafe"</span>
<span class="token punctuation">)</span>

<span class="token comment">//go:linkname open example1/open.Open</span>
<span class="token keyword">func</span> <span class="token function">open</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"Opening the door!"</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<p>Checkout the <a href="https://go.dev/play/p/ub2dX74b9w2">playground</a></p>
<h2>References</h2>
<ul>
<li><a href="http://siadat.github.io/blog/post/golinkname">http://siadat.github.io/blog/post/golinkname</a></li>
<li><a href="https://www.pixelstech.net/article/1649596852-The-magic-of-go%3Alinkname">https://www.pixelstech.net/article/1649596852-The-magic-of-go%3Alinkname</a></li>
<li><a href="https://lnquy.com/blog/go-linkname/">https://lnquy.com/blog/go-linkname/</a></li>
</ul>
<hr>
<p>The road to success is always under construction</p>
]]></description>
    </item>
    
    <item>
      <title>Pie holes are just munchkins</title>
      
      
      <link>https://glubbdubdrib.com/munchkins/</link>
      <guid isPermaLink="true">https://glubbdubdrib.com/munchkins/</guid>
      <pubDate>Fri, 13 Jan 2023 00:00:00 +0000</pubDate>
      <description><![CDATA[<p>2023 already. Nice. More layoffs. Not so nice. I decided to setup the <a href="https://pi-hole.net/">Pi-hole</a> recently to reduce the amount of tracking and ads on my network.<br>
A pie hole is just a munchkin while a Pi-hole is a program used to block unwanted network traffic. Traffic is blocked at the DNS level using a concept known as <a href="https://en.wikipedia.org/wiki/DNS_sinkhole">DNS Sinkhole</a>.<br>
DNS sinkholes are used to takedown malware (prevent bots from connecting to malicious domains).</p>
<p>Pi-hole uses this concept to block devices from connecting to certain servers. It uses ad lists (which you can import from Github) to block any requests to those addresses.<br>
<img src="/posts/piehole/adlist.png" alt="Ad List Management"></p>
<h2>Setup raspberry pi</h2>
<p>Follow their setup <a href="https://pi-hole.net/">guide</a> for an easy way to install the pi-hole. Read on for the longer way =).<br>
Download the Raspberry Pi OS Lite version to reduce the number of extra packages.<br>
Flash it onto the SD card using something like <a href="https://www.balena.io/etcher/">balenaEtcher</a>.<br>
Next, navigate to the SD card in your terminal. Add a few files to enable ssh.</p>
<pre class="language-sh"><code class="language-sh">$ <span class="token function">touch</span> <span class="token function">ssh</span>
$ openssl <span class="token function">passwd</span> <span class="token parameter variable">-6</span> <span class="token parameter variable">-salt</span> <span class="token string">'1234567890'</span> <span class="token parameter variable">-stdin</span> <span class="token operator">&lt;&lt;&lt;</span> <span class="token string">'raspberry'</span> <span class="token operator">></span> userconf.txt</code></pre>
<p>Note: for macOS make sure your openssl version is correct.</p>
<p>Insert the SD card, connect to your ethernet and power on your raspberry pi.<br>
Find the raspberry pi ip via the router or scanning your network.<br>
Verify you can ssh into the pi:</p>
<pre class="language-sh"><code class="language-sh">$ <span class="token function">ssh</span> pi@<span class="token operator">&lt;</span>ip address<span class="token operator">></span></code></pre>
<p>Set a static ip address on the pi.</p>
<h2>Setup pi-hole</h2>
<p>Now that the pi is up, ssh into the pi and install the pi-hole software:</p>
<pre class="language-sh"><code class="language-sh">$ <span class="token function">curl</span> <span class="token parameter variable">-sSL</span> https://install.pi-hole.net <span class="token operator">|</span> <span class="token function">bash</span></code></pre>
<p>After a few prompts you will have the pi-hole running.<br>
Verify it is running by logging on to the admin panel.<br>
You should see the dashboard below:<br>
<img src="/posts/piehole/dashboard.png" alt="Pi-hole dashboard"></p>
<p>Congrats on setting it up!</p>
<hr>
<p>To build or not to build...</p>
]]></description>
    </item>
    
    <item>
      <title>Zipf&#39;s Law</title>
      
      
      <link>https://glubbdubdrib.com/zipf-it/</link>
      <guid isPermaLink="true">https://glubbdubdrib.com/zipf-it/</guid>
      <pubDate>Mon, 22 Aug 2022 00:00:00 +0000</pubDate>
      <description><![CDATA[<p>I was reading a <a href="https://www.microsoft.com/en-us/research/publication/bitfunnel-revisiting-signatures-search/">paper</a> on Bloom Filters where the authors mention <a href="https://en.wikipedia.org/wiki/Zipf%27s_law">Zipfian distribution</a>.<br>
Zipfian distribution or Zipf's law is an inverse relation distribution. It looks different from the normal/standard &quot;bell shaped&quot; distribution. By multiplying the rank and frequency of any point on the distribution we should be close to a constant regardless of which point we choose.</p>
<p>This distribution can be seen in word frequencies across all languages. There seems to be a tradeoff between short one syllable words (easier for humans to speak) and the chance of miscommunication.</p>
<p>Following this <a href="https://www.youtube.com/watch?v=aVmf8MKev5M">video</a>, I took the <a href="https://www.gutenberg.org/ebooks/1184">text</a> of <em>The Count of Monte Cristo</em> and ran a word frequency analysis on the corpus using <a href="https://www.laurenceanthony.net/software/antconc/">AntConc</a>.<br>
Then I uploaded the results to Google Sheets and created the chart below:<br>
<img src="/posts/zipf/zipf-diagram.png" alt="Zipf distribution"></p>
<p>Notice how the corpus follows the same Zipf's distribution.</p>
<hr>
<p>Roll up twenty Zig Zags out of one Zipf - Juicy J</p>
]]></description>
    </item>
    
    <item>
      <title>Steady at the helm</title>
      
      
      <link>https://glubbdubdrib.com/steady-at-the-helm/</link>
      <guid isPermaLink="true">https://glubbdubdrib.com/steady-at-the-helm/</guid>
      <pubDate>Tue, 21 Jun 2022 00:00:00 +0000</pubDate>
      <description><![CDATA[<p>&quot;Learning is fun&quot; is what tell myself each time I probe k8s. This time I decided to dig into <a href="https://helm.sh/">Helm</a>.<br>
Helm is a package manager for Kubernetes. That just means we can write our k8s services in code similar to <a href="https://www.terraform.io/">Terraform</a>.</p>
<p>Helm is like a <a href="https://en.wikipedia.org/wiki/Template_processor">template processor</a>. It consists of yaml files with two types of files: <code>Chart.yaml</code> and <code>values.yaml</code>.<br>
The chart file contains keys and templated values such as these:</p>
<pre class="language-yaml"><code class="language-yaml"><span class="token key atrule">tree</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token punctuation">{</span> .Value.treeType <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre>
<p>Helm is used to keep infrastructure as code, allowing for quick deploys and rollbacks to the cluster.</p>
<h4>Setup</h4>
<p>Here's a quick run through of how to get started.<br>
Create a project first</p>
<pre class="language-sh"><code class="language-sh">helm create <span class="token operator">&lt;</span>project name<span class="token operator">></span></code></pre>
<p>Add some values to the <code>values.yaml</code> file:</p>
<pre class="language-yaml"><code class="language-yaml"><span class="token key atrule">favorite</span><span class="token punctuation">:</span>
  <span class="token key atrule">drink</span><span class="token punctuation">:</span> grog</code></pre>
<p>Add a <code>ConfigMap</code> template in <code>templates/configmap.yaml</code>:</p>
<pre class="language-yaml"><code class="language-yaml"><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> v1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> ConfigMap
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
    <span class="token key atrule">name</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token punctuation">{</span> .Release.Name <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">-</span>configmap<span class="token punctuation">-</span><span class="token punctuation">{</span><span class="token punctuation">{</span> .Release.Namespace <span class="token punctuation">}</span><span class="token punctuation">}</span>
<span class="token key atrule">data</span><span class="token punctuation">:</span>
    <span class="token key atrule">drink</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token punctuation">{</span> .Values.favorite.drink <span class="token punctuation">|</span> quote <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre>
<p>Note the <code>.Release</code> object. Helm has a few built-in <a href="https://helm.sh/docs/chart_template_guide/builtin_objects/">objects</a>.<br>
Note also the pipe to a built-in function <code>quote</code> which will quote the drink value.</p>
<p>Now get a dry-run output first to see the compute value:</p>
<pre class="language-sh"><code class="language-sh">helm <span class="token function">install</span> <span class="token operator">&lt;</span>release name<span class="token operator">></span> <span class="token builtin class-name">.</span> <span class="token parameter variable">--debug</span> --dry-run

<span class="token punctuation">..</span>.
COMPUTED VALUES:
favorite:
  drink: grog
<span class="token punctuation">..</span>.
MANIFEST:
---
<span class="token comment"># Source: ./templates/configmap.yaml</span>
apiVersion: v1
kind: ConfigMap
metadata:
    name: <span class="token operator">&lt;</span>release name<span class="token operator">></span>-configmap-default
data:
    drink: <span class="token string">"grog"</span>
</code></pre>
<p>Congrats on getting up and running with helm.</p>
<hr>
<p>Anyone can hold the helm when the seas are calm - Publius Syrus</p>
]]></description>
    </item>
    
    <item>
      <title>Improve your developer workflow in Go</title>
      
      
      <link>https://glubbdubdrib.com/golang-ci/</link>
      <guid isPermaLink="true">https://glubbdubdrib.com/golang-ci/</guid>
      <pubDate>Tue, 12 Jan 2021 00:00:00 +0000</pubDate>
      <description><![CDATA[<p>I decided to work on improving my workflow in Go. Some of the things I had in mind going into this project were:</p>
<ul>
<li>Building and testing on each PR and on the master branch</li>
<li>Linting on PRs</li>
<li>Auto formatting on PRs</li>
<li>Deploy previews on PRs</li>
</ul>
<p>I created a repo <a href="https://github.com/iamnotaturtle/go-ci">go-ci</a> with a simple test server.<br>
Next I started browsing the GitHub Marketplace for existing actions/apps I could use.</p>
<h4>Build, Test, Benchmark...Oh My</h4>
<p>This required a few actions. I used one separate action for building and testing.<br>
Another action I thought was cool allowed me to run a benchmark test and upload the results to GitHub pages.</p>
<h4>Lint Rollers</h4>
<p>I used an existing action for linting which under the hood used <code>golangci-lint</code>.<br>
This was nice because it supported multiple linters and would catch more issues.</p>
<h4>Auto Format</h4>
<p>For formatting, I saw a few actions which would fail a build for unformatted code.<br>
However, I really wanted to auto format the Go code on each PR since this was a repetitive task.<br>
I looked around and saw a few existing actions for JS projects and decided to create a similar one.<br>
I created my own action using <code>gofumpt</code> underneath and published it to the <a href="https://github.com/marketplace/actions/auto-gofmt">Marketplace</a>.</p>
<h4>Sneak Peek Previews</h4>
<p>I wanted each PR to have a deployable app. The quickest way for me was to setup a Heroku pipeline and enable Review apps.<br>
While this works, there is probably a better way of doing this.</p>
<p>And that's it.</p>
<hr>
<p>Just do it - Shia Surprise</p>
]]></description>
    </item>
    
    <item>
      <title>Trace Warnings with Node</title>
      
      
      <link>https://glubbdubdrib.com/trace-warnings/</link>
      <guid isPermaLink="true">https://glubbdubdrib.com/trace-warnings/</guid>
      <pubDate>Fri, 01 Jan 2021 00:00:00 +0000</pubDate>
      <description><![CDATA[<p>When upgrading to Node 14, I ran into this issue where running the test suite would throw a set of warnings like so:</p>
<pre><code>(node:79706) Warning: Accessing non-existent property 'cat' of module exports inside circular dependency
(Use `node --trace-warnings ...` to show where the warning was created)
(node:79706) Warning: Accessing non-existent property 'cd' of module exports inside circular dependency
(node:79706) Warning: Accessing non-existent property 'chmod' of module exports inside circular dependency
(node:79706) Warning: Accessing non-existent property 'cp' of module exports inside circular dependency
</code></pre>
<p>One way of finding out what packages were throwing these warnings was by running the same command but with the <code>--trace-warnings</code> option:</p>
<pre><code>npx cross-env NODE_OPTIONS=&quot;--trace-warnings&quot; yarn test
</code></pre>
<p>This helped in pinpointing which packages needed to be updated!</p>
<h2>Bonus</h2>
<p>Here is a contrived example of two classes depending on each other:</p>
<pre class="language-js"><code class="language-js"><span class="token comment">// a.js</span>
<span class="token keyword">const</span> <span class="token constant">B</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./b'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">class</span> <span class="token class-name">A</span> <span class="token punctuation">{</span>
    <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>b <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">B</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>b<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">A</span><span class="token punctuation">(</span><span class="token string">'cat'</span><span class="token punctuation">)</span>

module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token constant">A</span><span class="token punctuation">;</span>

<span class="token comment">// b.js</span>
<span class="token keyword">const</span> <span class="token constant">A</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./a'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">class</span> <span class="token class-name">B</span> <span class="token punctuation">{</span>
    <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token constant">A</span><span class="token punctuation">;</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>a<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>

    <span class="token function">log</span><span class="token punctuation">(</span><span class="token parameter">stuff</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>stuff<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token constant">B</span><span class="token punctuation">;</span>

<span class="token comment">// package.json</span>
  <span class="token string-property property">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token string-property property">"build"</span><span class="token operator">:</span> <span class="token string">"node a.js"</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span></code></pre>
<p>Now building our files gives us this warning:</p>
<pre><code>$ yarn build

(node:18952) Warning: Accessing non-existent property 'Symbol(nodejs.util.inspect.custom)' of module exports inside circular dependency
(Use `node --trace-warnings ...` to show where the warning was created)
</code></pre>
<p>Now using <code>--trace-warnings</code> we can see where this issue is happening:</p>
<pre><code>$ npx cross-env NODE_OPTIONS=&quot;--trace-warnings&quot; yarn build

(node:18978) Warning: Accessing non-existent property 'Symbol(nodejs.util.inspect.custom)' of module exports inside circular dependency
    at emitCircularRequireWarning (node:internal/modules/cjs/loader:698:11)
    at Object.get (node:internal/modules/cjs/loader:712:5)
    at formatValue (node:internal/util/inspect:746:30)
    at inspect (node:internal/util/inspect:330:10)
    at formatWithOptionsInternal (node:internal/util/inspect:1998:40)
    at formatWithOptions (node:internal/util/inspect:1880:10)
    at console.value (node:internal/console/constructor:327:14)
    at console.log (node:internal/console/constructor:363:61)
    at new B (/Users/ygaberman/programs/test/b.js:6:17)
    at new A (/Users/ygaberman/programs/test/a.js:7:18)
</code></pre>
<p>The last two lines show us where the dependency is. This is quite useful for chasing down any circular dependencies!</p>
<hr>
<p>Can we fix it? Yes.</p>
]]></description>
    </item>
    
    <item>
      <title>Javascript Proxy</title>
      
      
      <link>https://glubbdubdrib.com/proxy/</link>
      <guid isPermaLink="true">https://glubbdubdrib.com/proxy/</guid>
      <pubDate>Sun, 11 Oct 2020 00:00:00 +0000</pubDate>
      <description><![CDATA[<p>While browsing through some programming books, I came across <a href="https://www.amazon.com/Understanding-ECMAScript-Definitive-JavaScript-Developers/dp/1593277571">Understanding ECMAScript 6</a> which had a cool section on <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy">Proxies</a>.<br>
Proxies are objects which we can use to intercept operations on <code>target</code> objects. Below, we define a Proxy for an empty object where we override the setter.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> target <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> proxy <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Proxy</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> <span class="token punctuation">{</span>
  <span class="token function-variable function">set</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">obj<span class="token punctuation">,</span> prop<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Setting </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>prop<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> to </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>value<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span>
    obj<span class="token punctuation">[</span>prop<span class="token punctuation">]</span> <span class="token operator">=</span> value<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Now when we set a value on our proxy, our target will have that value and our log will be called:</p>
<pre class="language-js"><code class="language-js">proxy<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">'turtle'</span>
<span class="token string">'Setting name to turtle'</span></code></pre>
<p>Proxies are built using the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect">Reflect</a> API and can be used for validating getters/setters. The example below shows how we can throw an error if a property does not exist on the target.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> target <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'hi'</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> proxy <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Proxy</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> <span class="token punctuation">{</span>
  <span class="token function-variable function">get</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">target<span class="token punctuation">,</span> prop<span class="token punctuation">,</span> receiver</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>prop <span class="token keyword">in</span> receiver<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">return</span> Reflect<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> prop<span class="token punctuation">,</span> receiver<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">'property does not exist!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

proxy<span class="token punctuation">.</span>name <span class="token comment">// 'hi'</span>
proxy<span class="token punctuation">.</span>dne <span class="token comment">// Uncaught Error: property does not exist!</span></code></pre>
<p>Some use cases for proxies:</p>
<ul>
<li>Validation: Is the input a valid integer?</li>
<li>Caching: Can we return the data from memory instead of fetching from our api?</li>
<li>Observability: Can we be notified when an object's state is changed?</li>
</ul>
<hr>
<p>Go out there and build!</p>
]]></description>
    </item>
    
    <item>
      <title>20,000 times out of my league</title>
      
      
      <link>https://glubbdubdrib.com/2048/</link>
      <guid isPermaLink="true">https://glubbdubdrib.com/2048/</guid>
      <pubDate>Sun, 19 Apr 2020 00:00:00 +0000</pubDate>
      <description><![CDATA[<p>This project took way longer than I intended...</p>
<p>Today we'll explore building 2048 with <a href="https://github.com/sveltejs/svelte">svelte</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout">CSS grid layout</a>.<br>
This post is short, so jump down to the resources to get started on your own!</p>
<p>Svelte is a front end framework promising less boilerplate code. Less is more, so <em>less</em> try it out.</p>
<pre class="language-bash"><code class="language-bash">npx degit sveltejs/template <span class="token number">2048</span>
<span class="token builtin class-name">cd</span> <span class="token number">2048</span>
<span class="token function">yarn</span>
<span class="token function">yarn</span> dev</code></pre>
<p>Once up and running, let's navigate to <code>localhost:5000</code>. Once there, let's add a 4x4 grid.<br>
When working with CSS grid, we set the container to <code>display:grid</code>, as well as other grid properties.<br>
Finally, let's set the properties of the cell (height, width, and how we will display the content).<br>
See the minimal example below:</p>
<pre class="language-css"><code class="language-css"><span class="token selector">.grid</span> <span class="token punctuation">{</span>
	<span class="token property">display</span><span class="token punctuation">:</span> grid<span class="token punctuation">;</span>
	<span class="token property">grid-gap</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span>
	<span class="token property">grid-template-columns</span><span class="token punctuation">:</span> 1fr 1fr 1fr 1fr<span class="token punctuation">;</span>
	<span class="token property">grid-auto-rows</span><span class="token punctuation">:</span> 1fr<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector">.cell</span> <span class="token punctuation">{</span>
	<span class="token property">width</span><span class="token punctuation">:</span> 48px<span class="token punctuation">;</span>
	<span class="token property">height</span><span class="token punctuation">:</span> 48px<span class="token punctuation">;</span>
	<span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
	<span class="token property">justify-content</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
	<span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>Once the layout is setup, we write some code to handle the key/touch events since we want to support both mobile and desktop.<br>
We use the <a href="https://github.com/john-doherty/swiped-events">swiped-events</a> repo to detect mobile swipes. Neat...</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> mobileKeyMap <span class="token operator">=</span> <span class="token punctuation">{</span>
	<span class="token string-property property">'swiped-up'</span><span class="token operator">:</span> <span class="token string">'ArrowUp'</span><span class="token punctuation">,</span>
	<span class="token string-property property">'swiped-down'</span><span class="token operator">:</span> <span class="token string">'ArrowDown'</span><span class="token punctuation">,</span>
	<span class="token string-property property">'swiped-left'</span><span class="token operator">:</span> <span class="token string">'ArrowLeft'</span><span class="token punctuation">,</span>
	<span class="token string-property property">'swiped-right'</span><span class="token operator">:</span> <span class="token string">'ArrowRight'</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
<span class="token keyword">const</span> mobileKeys <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>mobileKeyMap<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> <span class="token function-variable function">setupMobile</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
	mobileKeys<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token parameter">eventName</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
		document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span>eventName<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
			event<span class="token punctuation">.</span>key <span class="token operator">=</span> mobileKeyMap<span class="token punctuation">[</span>event<span class="token punctuation">.</span>type<span class="token punctuation">]</span><span class="token punctuation">;</span>
			<span class="token function">handleInput</span><span class="token punctuation">(</span>event<span class="token punctuation">)</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token function">setupMobile</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token function-variable function">handleInput</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
	<span class="token keyword">switch</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>key<span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token keyword">case</span> <span class="token string">'ArrowUp'</span><span class="token operator">:</span>
	<span class="token keyword">case</span> <span class="token string">'ArrowDown'</span><span class="token operator">:</span>
	<span class="token keyword">case</span> <span class="token string">'ArrowLeft'</span><span class="token operator">:</span>
	<span class="token keyword">case</span> <span class="token string">'ArrowRight'</span><span class="token operator">:</span>
		game<span class="token punctuation">.</span><span class="token function">handleInput</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span>
		game<span class="token punctuation">.</span>grid <span class="token operator">=</span> game<span class="token punctuation">.</span>grid<span class="token punctuation">;</span>
		<span class="token keyword">return</span><span class="token punctuation">;</span>
	<span class="token keyword">default</span><span class="token operator">:</span>
		<span class="token keyword">return</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre>
<p>And with a lot of help from <a href="https://rosettacode.org/wiki/2048">Rosetta Code</a>, we create a separate <code>game.js</code> class to handle the game logic.<br>
Finally, we create a separate svelte component to make it rain when the player wins:</p>
<div style="text-align: center;">
  <img src="/posts/svelte/game.gif" alt="Game Won!" style="height: 400px;" />
</div>
<h2>Resources</h2>
<ul>
<li><a href="https://codepen.io/camsong/pen/wcKrg">Original game</a></li>
<li><a href="https://rosettacode.org/wiki/2048">2048 in all languages</a></li>
<li><a href="https://github.com/iamnotaturtle/2048/">Repo</a></li>
</ul>
<hr>
<p>Quaerite Et Invenietis</p>
]]></description>
    </item>
    
    <item>
      <title>Building a site with Wix</title>
      
      
      <link>https://glubbdubdrib.com/wix/</link>
      <guid isPermaLink="true">https://glubbdubdrib.com/wix/</guid>
      <pubDate>Sun, 05 Apr 2020 00:00:00 +0000</pubDate>
      <description><![CDATA[<blockquote>
<p>TIL: Deque is an abbreviation for double-ended queue...amazing!</p>
</blockquote>
<p>This week, we'll take a brief look at how Wix works. Wix is a site builder useful for ecommerce and portfolios.<br>
It is a high level site builder, trading customization for quick setup and ease of use for non technical customers.</p>
<p>A <em>very</em> simplified flow of setting up a site is something like this:<br>
<img src="/posts/wix/flow.png" alt="Setting up a site flow"></p>
<center><i>Step 3 is often overlooked...</i></center>
<p>When building a site, Wix has a nice dashboard which lets us preview our site on both desktop and mobile.<br>
Further, if we enable their developer mode (Corvid), we can add our custom JavaScript for a given page or the whole site.<br>
While Wix can be a bit slow at times (toggling between previewing and editing the site is a pain),<br>
Wix does a great job of getting you up and running on your own.</p>
<p><img src="/posts/wix/wixwork.png" alt="Overview of editor"></p>
<center><i>What a beautiful cat</i></center>
<p>Give it a try!</p>
]]></description>
    </item>
    
    <item>
      <title>Deploy Previews</title>
      
      
      <link>https://glubbdubdrib.com/deploy-previews/</link>
      <guid isPermaLink="true">https://glubbdubdrib.com/deploy-previews/</guid>
      <pubDate>Thu, 26 Mar 2020 00:00:00 +0000</pubDate>
      <description><![CDATA[<p>In the land of CICD we have several ways of demoing our branches before merging to master.<br>
Pulling the branch and running it locally (Dockerized or not) or manually deploying to a server are just some ways of doing this.<br>
This post will talk about a few options we have to do this automatically.</p>
<p>Two cool options we can use are Netlify's <a href="https://docs.netlify.com/site-deploys/overview/">deploy previews</a><br>
and AWS Amplify's <a href="https://docs.aws.amazon.com/amplify/latest/userguide/pr-previews.html">web preview</a>.</p>
<p>Assuming we have a pipeline setup with either of those services, we can connect either platforms to our repo.<br>
After enabling deploy previews (usually by connecting either Netlify or AWS Amplify to our platform),<br>
we can see a preview of our pull request!</p>
<h3>Netlify</h3>
<p>For Netlify, we can see the GitHub checks below. Tapping on the details link will take us to the preview app.</p>
<p><img src="/posts/deploy-previews/netlify-preview.png" alt="Netlify PR Preview Link"></p>
<center><i>Tap on details link to preview</i></center>
<h3>AWS Amplify:</h3>
<p>For AWS Amplify, we have to do a few more steps. Our repo must be set to private, after which we can see the completed check below.</p>
<p><img src="/posts/deploy-previews/aws-amplify-preview.png" alt="AWS Amplify PR Preview Link"></p>
<center><i>Tap on details link to see the GitHub check</i></center>
<p>Unfortunately we can only get the link from the AWS Amplify console. Navigate to <code>App -&gt; App Settings -&gt; Previews</code> to get your preview URL.</p>
<hr>
<p>Go out there and try it out on your own!</p>
]]></description>
    </item>
    
  </channel>
</rss>

