<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Missing Token</title>
    <description>programming errata</description>
    <link>https://missingtoken.net/</link>
    <atom:link href="https://missingtoken.net/feed.xml" rel="self" type="application/rss+xml" />
    
      <item>
        <title>MacOS path_helper not so helpful</title>
        <description>&lt;p&gt;Do you use shell-based version managers like &lt;a href=&quot;https://github.com/nvm-sh/nvm&quot;&gt;nvm&lt;/a&gt;, &lt;a href=&quot;https://github.com/pyenv/pyenv&quot;&gt;pyenv&lt;/a&gt;, or &lt;a href=&quot;https://github.com/rbenv/rbenv&quot;&gt;rbenv&lt;/a&gt;, in combination with
&lt;a href=&quot;https://github.com/tmux/tmux&quot;&gt;tmux&lt;/a&gt; on macOS? If so, you may be in for a surprise. Outside of tmux and screen, version
managers will work fine, but inside the session, system or &lt;a href=&quot;https://brew.sh/&quot;&gt;Homebrew&lt;/a&gt; installed tools will be
used instead. What’s going on here?&lt;/p&gt;

&lt;!--more --&gt;

&lt;h2 id=&quot;path-helper&quot;&gt;Path Helper&lt;/h2&gt;

&lt;p&gt;MacOS has a utility called &lt;code class=&quot;highlighter-rouge&quot;&gt;path_helper&lt;/code&gt; that initializes the &lt;code class=&quot;highlighter-rouge&quot;&gt;PATH&lt;/code&gt; environment variable by
reading paths from &lt;em&gt;/etc/paths&lt;/em&gt; and then any file under &lt;em&gt;/etc/paths.d&lt;/em&gt;. The path helper utility
doesn’t technically set the &lt;code class=&quot;highlighter-rouge&quot;&gt;PATH&lt;/code&gt;, but will output the shell commands to set it accordingly. It is
&lt;code class=&quot;highlighter-rouge&quot;&gt;eval&lt;/code&gt;‘d by the first file sourced on a login shell for sh, bash, and zsh:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Code snippet found in /etc/profile and /etc/zprofile&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-x&lt;/span&gt; /usr/libexec/path_helper &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt; &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;/usr/libexec/path_helper &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;path-helper-and-existing-path&quot;&gt;Path Helper and Existing PATH&lt;/h2&gt;

&lt;p&gt;If you already have a &lt;code class=&quot;highlighter-rouge&quot;&gt;PATH&lt;/code&gt; variable set when invoking &lt;code class=&quot;highlighter-rouge&quot;&gt;path_helper&lt;/code&gt;, such as when you start a new
tmux session, &lt;code class=&quot;highlighter-rouge&quot;&gt;path_helper&lt;/code&gt; will ‘intelligently’ create a new &lt;code class=&quot;highlighter-rouge&quot;&gt;PATH&lt;/code&gt; by merging the loaded paths
with existing &lt;code class=&quot;highlighter-rouge&quot;&gt;PATH&lt;/code&gt; and removing duplicates. The problem is, while &lt;code class=&quot;highlighter-rouge&quot;&gt;path_helper&lt;/code&gt; deduplicates
paths, it doesn’t preserve order. If you have a custom path or paths prepended to the default list
in your &lt;em&gt;~/.bashrc&lt;/em&gt; or &lt;em&gt;~/.zshrc&lt;/em&gt;  and invoke the path helper, your custom path(s) will now be at
the &lt;em&gt;end&lt;/em&gt; of the &lt;code class=&quot;highlighter-rouge&quot;&gt;PATH&lt;/code&gt; variable. This effectively disables all your version managers by
prioritizing system binaries over them.&lt;/p&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;

&lt;p&gt;Luckily there is a setting in tmux to tell it to avoid creating a login shell when starting a new
session. This avoids sourcing &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/[z]profile&lt;/code&gt;, and &lt;code class=&quot;highlighter-rouge&quot;&gt;path_helper&lt;/code&gt; does not get invoked. Simply add
this setting to your &lt;code class=&quot;highlighter-rouge&quot;&gt;tmux.conf&lt;/code&gt; and you should be good to go:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Don't create login shells
set -g default-command &quot;${SHELL}&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If having tmux create login shells is somehow a requirement for you, your only other choice is to
create or edit the first user controlled file that gets sourced in a login shell, either
&lt;code class=&quot;highlighter-rouge&quot;&gt;~/.bash_profile&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;~/.zprofile&lt;/code&gt;, and add some code to fix your &lt;code class=&quot;highlighter-rouge&quot;&gt;PATH&lt;/code&gt; variable by comparing the
existing &lt;code class=&quot;highlighter-rouge&quot;&gt;PATH&lt;/code&gt; against the paths generated when running &lt;code class=&quot;highlighter-rouge&quot;&gt;path_helper&lt;/code&gt; in a clean environment and
then rebuilding the &lt;code class=&quot;highlighter-rouge&quot;&gt;PATH&lt;/code&gt; variable with user-defined paths prepended to the system-defined paths:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;reorganize_login_subshell_path&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# save path as old_path&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;old_path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# run path_helper against an empty PATH&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;''&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt; &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;/usr/libexec/path_helper &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# At this point the PATH contains only system-wide paths.&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# If paths are the same this is not a subshell or no user-defined paths are&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# set. In other words, the PATH is correct and there is no work to be done.&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$old_path&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
        return
    fi&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# Use parameter substitution to subtract system-wide paths from old_path,&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# leaving only user-defined paths. &quot;${var#Pattern}&quot; means &quot;Remove from $var&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# the shortest part of $Pattern that matches the front end of $var.&quot;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;user_defined_paths&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;old_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;:&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# Rebuild PATH with user-defined paths prepended to system-wide paths.&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$user_defined_paths&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-x&lt;/span&gt; /usr/libexec/path_helper &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;reorganize_login_subshell_path
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# remove path reorganization function to avoid cluttering environment&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;unset&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; reorganize_login_subshell_path
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The latter approach here is not recommended as it attempts to solve the problem of &lt;code class=&quot;highlighter-rouge&quot;&gt;PATH&lt;/code&gt; munging
with more &lt;code class=&quot;highlighter-rouge&quot;&gt;PATH&lt;/code&gt; munging, making it all the more difficult to reason about the state of your shell
environment.&lt;/p&gt;

</description>
        <pubDate>Tue, 15 May 2018 00:48:23 -0600</pubDate>
        <link>https://missingtoken.net/2018/05/15/path-helper-not-so-helpful/</link>
        <guid isPermaLink="true">https://missingtoken.net/2018/05/15/path-helper-not-so-helpful/</guid>
      </item>
    
      <item>
        <title>The Why of &quot;Wat&quot; [Ruby edition]</title>
        <description>&lt;p&gt;In his wonderfully sarcastic lightning talk, Wat, Gary Bernhardt explores the
dark side of Ruby and Javascript with examples that seem to defy logic.  When I
first saw &lt;a href=&quot;https://www.destroyallsoftware.com/talks/wat&quot;&gt;&lt;em&gt;Wat&lt;/em&gt;&lt;/a&gt;, I immediately
wanted to know more. How do these strange behaviors come about? Is it an
interpreter error, designed into the language, or something else entirely? If
the behavior is intentional, what is the reasoning behind it? I decided to take
the plunge and find out for myself.&lt;/p&gt;

&lt;!--more --&gt;

&lt;h2 id=&quot;lets-talk-about-ruby&quot;&gt;Let’s talk about Ruby&lt;/h2&gt;

&lt;h3 id=&quot;undefined-variable-self-assignment&quot;&gt;Undefined variable self assignment&lt;/h3&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; NameError: undefined local variable or method `a' for main:Object&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; NameError: undefined local variable or method `b' for main:Object&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; NameError: undefined local variable or method `b' for main:Object&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; nil&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Why would Ruby transform an undefined variable to &lt;code class=&quot;highlighter-rouge&quot;&gt;nil&lt;/code&gt; in self assignment?
Let’s first breakdown a typical variable assignment in Ruby:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;ol&gt;
  &lt;li&gt;Ruby initializes &lt;code class=&quot;highlighter-rouge&quot;&gt;foo&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;nil&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Ruby evaluates the expression on the right-hand side. In this case the
result is simply &lt;code class=&quot;highlighter-rouge&quot;&gt;4&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Ruby assigns the result of the right-hand side evaluation (&lt;code class=&quot;highlighter-rouge&quot;&gt;4&lt;/code&gt;) to &lt;code class=&quot;highlighter-rouge&quot;&gt;foo&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And now the same breakdown of a self assignment:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;ol&gt;
  &lt;li&gt;Ruby initializes &lt;code class=&quot;highlighter-rouge&quot;&gt;foo&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;nil&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Ruby evaluates the expression on the right-hand side. To do this, Ruby looks
up the value of &lt;code class=&quot;highlighter-rouge&quot;&gt;foo&lt;/code&gt;, which by this point is &lt;code class=&quot;highlighter-rouge&quot;&gt;nil&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Ruby assigns the result of the right-hand side evaluation (&lt;code class=&quot;highlighter-rouge&quot;&gt;nil&lt;/code&gt;) to &lt;code class=&quot;highlighter-rouge&quot;&gt;foo&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The key point here is that Ruby will always initialize the variable on the
left-hand side &lt;em&gt;before&lt;/em&gt; evaluating the expression on the right-hand side. This
guarantees that any undefined variables on the left-hand side will be defined
by the time the right-hand side is evaluated.&lt;/p&gt;

&lt;p&gt;We now know &lt;em&gt;how&lt;/em&gt; Ruby allows for self assignment of an undefined variable, but
that still leaves &lt;em&gt;why&lt;/em&gt;. One reason this seemingly odd behavior exists is to
accommodate a somewhat common idiom – conditional setting of variables:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TaskList&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;tasks&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@tasks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@tasks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;(Note that the above is usually written &lt;code class=&quot;highlighter-rouge&quot;&gt;@tasks ||= []&lt;/code&gt;, though the two
aren’t equivalent&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.)&lt;/p&gt;

&lt;p&gt;If &lt;code class=&quot;highlighter-rouge&quot;&gt;@tasks&lt;/code&gt; is undefined, and Ruby doesn’t initialize &lt;code class=&quot;highlighter-rouge&quot;&gt;@tasks&lt;/code&gt; before
evaluating the right-hand side of the assignment, this idiom would not work as
intended.&lt;/p&gt;

&lt;h3 id=&quot;ruby-and-bare-words&quot;&gt;Ruby and bare words&lt;/h3&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;ruby&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;has&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;no&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bare&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;words&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; NameError: undefined local variable or method `words'&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;method_missing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;ruby&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;has&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bare&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;words&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;ruby has bare words&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This one is nothing more than an interesting application of language features,
some more well known than others. The first and probably best known feature is
that parenthesis are optional in Ruby method calls. Because of this, Ruby
interprets &lt;code class=&quot;highlighter-rouge&quot;&gt;ruby has no bare words&lt;/code&gt; as if we wrote
&lt;code class=&quot;highlighter-rouge&quot;&gt;ruby( has( no( bare( words ) ) )&lt;/code&gt;. Second, when making a method call, Ruby
searches the current scope for a matching method definition. If it cannot find
one, it passes the method name in question to &lt;code class=&quot;highlighter-rouge&quot;&gt;method_missing&lt;/code&gt;&lt;sup id=&quot;fnref:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;. You can define
your own &lt;code class=&quot;highlighter-rouge&quot;&gt;method_missing&lt;/code&gt; to provide extra runtime functionality. In this case,
our &lt;code class=&quot;highlighter-rouge&quot;&gt;method_missing&lt;/code&gt; takes the passed in method name (plus zero or more other
arguments) and returns a string of all those arguments joined together. Let’s
break up the example to illustrate how the string is built:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# Starting with the innermost method call&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;method_missing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;words&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;words&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;method_missing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;bare&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;words&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;bare words&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;method_missing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;has&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;bare words&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;has bare words&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;method_missing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ruby&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;has bare words&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;ruby has bare words&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Ruby behaves this way because part of its core functionality has been broken,
making the &lt;em&gt;why&lt;/em&gt; pretty pointless here. Note that in Ruby 1.9.3+, arguments are
passed to &lt;code class=&quot;highlighter-rouge&quot;&gt;method_missing&lt;/code&gt; as symbols instead of strings, which causes infinite
recursion. This is because
&lt;a href=&quot;http://www.ruby-doc.org/core-2.1.4/Array.html#method-i-join&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Array#join&lt;/code&gt;&lt;/a&gt;
attempts to convert the symbols to string objects by calling &lt;code class=&quot;highlighter-rouge&quot;&gt;to_str&lt;/code&gt;, and
since no &lt;code class=&quot;highlighter-rouge&quot;&gt;to_str&lt;/code&gt; method is defined for the &lt;code class=&quot;highlighter-rouge&quot;&gt;Symbol&lt;/code&gt; class, the method call
gets passed to – you guessed it – &lt;code class=&quot;highlighter-rouge&quot;&gt;method_missing&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;lets-talk-about-javascript&quot;&gt;Let’s talk about Javascript&lt;/h2&gt;

&lt;p&gt;As it turns out, the Javascript portion of &lt;em&gt;wat&lt;/em&gt; has already been covered by
Adam Iley’s well written
&lt;a href=&quot;http://blog.caplin.com/2012/01/27/the-why-of-wat/&quot;&gt;blog post&lt;/a&gt;. I discovered
this post while researching my own, and was surprised to find it had not only
already been written, but with an identical title! Thanks Adam!&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;http://dablog.rubypal.com/2008/3/25/a-short-circuit-edge-case&quot;&gt;http://dablog.rubypal.com/2008/3/25/a-short-circuit-edge-case&lt;/a&gt; &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;http://www.ruby-doc.org/core-2.1.0/BasicObject.html#method-i-method_missing&quot;&gt;http://www.ruby-doc.org/core-2.1.0/BasicObject.html#method-i-method_missing&lt;/a&gt; &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Thu, 13 Nov 2014 23:48:23 -0700</pubDate>
        <link>https://missingtoken.net/2014/11/13/the-why-of-wat-ruby-edition/</link>
        <guid isPermaLink="true">https://missingtoken.net/2014/11/13/the-why-of-wat-ruby-edition/</guid>
      </item>
    
  </channel>
</rss>
