<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Penelope Phippen</title>
    <description>The latest articles on DEV Community by Penelope Phippen (@penelope_zone).</description>
    <link>https://dev.to/penelope_zone</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F194867%2F75eb2b9b-268d-45fe-8516-01dadef3f89a.png</url>
      <title>DEV Community: Penelope Phippen</title>
      <link>https://dev.to/penelope_zone</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/penelope_zone"/>
    <language>en</language>
    <item>
      <title>The incredible weight of being a trans woman in tech</title>
      <dc:creator>Penelope Phippen</dc:creator>
      <pubDate>Wed, 31 Mar 2021 18:12:20 +0000</pubDate>
      <link>https://dev.to/penelope_zone/the-incredible-weight-of-being-a-trans-woman-in-tech-45n0</link>
      <guid>https://dev.to/penelope_zone/the-incredible-weight-of-being-a-trans-woman-in-tech-45n0</guid>
      <description>&lt;p&gt;Content warnings for bullying, abuse, trans-misogyny, the general state of horibbleness in tech. If any of these things are squicky for you, I absolutely won't blame you if you want to skip this one.&lt;/p&gt;

&lt;p&gt;I missed writing a #shecoded this year, but it's trans day of visibility, and I have a tradition of posting posts about the intersection of being transgender and my life in technology here on dev.to. So, let's get into it.&lt;/p&gt;

&lt;p&gt;First, a tiny amount of personal news. I've switched from identifying strictly as a trans woman, to identifying as demifemme. I use she or they pronouns now. Hearing a mix is nice, but if it's hard for you, 'she' is fine. It's also mostly correct to still think of me as a woman. To dig into it just a smidge, to me, demifemme means that I mostly identify as feminine, but gender is more complicated than that, and I find woman just a little bit reductive. With that, let's dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  Being socialised as male left me with a deep hurt
&lt;/h2&gt;

&lt;p&gt;I am a survivor of my upbringing. I don't blame my parents, or my teachers, or those around me when I grew up, as such. This is a wider societal problem. I remember, so clearly, kids in my secondary school bullying me for being "girly". As if the worst possible thing that a young boy could be is effeminate. Obviously, young kids being actively and repeatedly horrible to another kid isn't acceptable, but looking back, I find it so fascinating that the direction from which this abuse came was, in at least part, gendered. I see it now as if society itself was rejecting me.&lt;/p&gt;

&lt;p&gt;So, something happened within me that I can only describe as my brain protecting itself. A persona who was a man/male came forward. It was as if the person I actually am was buried, behind this full shield of a completely different person. That person grew throughout my adolescence and was the me many of you will have known throughout the majority of my life. He wasn't, however, a full person. It was more like a half person, as a shield, burying and protecting the little girl within. She couldn't take any more of the hurt, and so he came to the defense. This hurt, &lt;strong&gt;so much&lt;/strong&gt;. Imagine fully burying who you actually are in order to make life bearable. That's what I did from around the time I was an adolescent, until I was 28. Society made it so hard to not conform in this way that I literally psychologically buried myself as a person, in order to be able to survive.&lt;/p&gt;

&lt;p&gt;Eventually though, it became clear, that I couldn't take any more of this. That continuing to live as this shell of a person was hurting me too much. It took a long time for me to realise what was going on. For the little girl within to break through and claim that this was my body, and that I wanted to be who I am. To understand that all the pain and suffering so far had been a form of protection that I actually did not want. That it was time for him to rest, and for me to take over. When I finally realised that it was time to say goodbye to the man who had been protecting me for all these years, I cried a great deal. It was like letting go of an old friend. There is a sense in which I still miss him to this day.&lt;/p&gt;

&lt;p&gt;Folks who don't understand trans issues talk about being socialized as male as a 'bad thing'. As if it's the fault of the trans person. In fact, I think of it as an abuse I bore and grew up with, that I survived, and am working to undo within myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ok, that's super touching, what does this have to do with tech?
&lt;/h2&gt;

&lt;p&gt;Our industry looks a certain way. If you're in any sense underrepresented, you will have been in &lt;strong&gt;that&lt;/strong&gt; important meeting where it's 3-11 cis white men, and then, just you. &lt;/p&gt;

&lt;p&gt;I've been on the other side of this. Before I transitioned, I was in that group. The large amorphous blob of dudes that makes up our industry. And boy, did I act like it. Before I transitioned, I was most definitely bathing in the toxic masculinity that makes up the tech industry. See, for me, that was all I really knew what to do, emulate. Not actually being a man meant that when I thought I was one, all I could really do is copy what other cis men do, but not having the best basis for it, it was a warped copy. I was loud, I was brash, I would definitely cut in when others were talking if I thought they were wrong, and here's the thing: it was effective.&lt;/p&gt;

&lt;p&gt;There's something present today in the culture of tech that is indescribable, a code of how we act and how we discuss that is implicit in who's in the room. The set of things that we say and do to affect change, build alignment, and discuss technical decisions. This code, this way of interacting, it's borne from the fact that much of the time, it's just cis men talking to cis men, with no diverse voices in the room to change the pattern of conversation. De facto, when working with folks from this set, it feels so much like you have to engage with them in the way they speak, or you won't be heard.&lt;/p&gt;

&lt;p&gt;When I speak to cis women about this, they also detect that it's there. They know that there's a way the dudes are talking that they can't quite replicate. They tell me that when they try, they're often given the kind of gendered feedback that so many of us are used to receiving "She's aggressive", "She's loud", "She needs to be less assertive". It's like as much as they're doing it, it's not quite perceived as native, and some force pushes back against them. But there's something inherently twisted in this, which is that women feel the need to replicate this in the first place. &lt;/p&gt;

&lt;p&gt;This brings me back to myself, and my lived experience. One thing that's different between me, and a cis woman, is that I &lt;strong&gt;can&lt;/strong&gt; replicate dudespeak natively. I did so for a decade before I transitioned, because it was all I knew how to do. I do so in a way where it's clear to me that they perceive it as native. I feel a deep need to do this in order to be effective at my job. However, every time I do this it hurts me so deeply. It puts me back in the place of abuse, of literally subsuming my personality to protect myself, of pretending to be a man to get the job done. I don't really make a conscious choice about this. The behaviour is so deeply ingrained it happens almost automatically. I try not to use dudespeak to get the job done, but it drags me back in every. single. time. This is a byproduct of the environment. It's like there's an implicit statement widely in tech (this doesn't just happen at work, this happens in almost every tech environment I'm in) that because it's predominantly cis men, you have to emulate them to be successful.&lt;/p&gt;

&lt;p&gt;And so, this brings me back to the weight of being a trans woman in tech. &lt;strong&gt;I have a choice between either being less effective at my job or inducing gender dysphoria at almost every large complex decision point&lt;/strong&gt;. Because I'm senior, and because there aren't so many trans ladies in tech, I feel a need to well represent the group, and so I am repeatedly taking the tradeoff that hurts me, but makes me effective. Until such time as tech looks less monocultural, I'll have to continue to do this. I'll have to continue to hurt myself. Nobody can see this happening because it's an internal decision I am making, so on this trans day of visibility, I'd just like you to pause and think about how you can make the industry more comfortable for trans women and other trans and non-binary folks, by making the spaces around you more diverse and inclusive.&lt;/p&gt;

</description>
      <category>inclusion</category>
      <category>wecoded</category>
    </item>
    <item>
      <title>What is the halting problem, anyway?</title>
      <dc:creator>Penelope Phippen</dc:creator>
      <pubDate>Sun, 20 Sep 2020 18:30:06 +0000</pubDate>
      <link>https://dev.to/penelope_zone/what-is-the-halting-problem-anyway-5954</link>
      <guid>https://dev.to/penelope_zone/what-is-the-halting-problem-anyway-5954</guid>
      <description>&lt;p&gt;You may have asked yourself, are there problems computers can't solve? And, for example, ventured in to deep philosophical questions like "do we all see the same colors?", "Is the sky really blue?", etc. And while &lt;a href="https://www.technologyreview.com/2020/07/20/1005454/openai-machine-learning-language-generator-gpt-3-nlp/"&gt;GPT-3&lt;/a&gt; might be able to convincingly fool a human it knowns the answers, it really doesn't. Unfortunately, you've run to a class of very ambiguous, ill-defined problem. We don’t know if computers can solve these problems because they’re so ill-defined that we can’t model them mathematically, and so we can’t cleanly define “solved”.&lt;/p&gt;

&lt;p&gt;So, let’s look at a different class of problem. If you think about it, we mostly dictate very well defined problems to computers, like "move these bits of data out of JSON and in to a database", "add all these numbers together", and so on. So, this sort of brings forward this question: Are there well defined questions to which computers cannot produce the answer?&lt;/p&gt;

&lt;p&gt;Well, we have a class of problem to which we know computers can trivially solve. Let's look at an example of a well defined problem we know with 100% certainty computers can't solve.&lt;/p&gt;

&lt;h1&gt;
  
  
  The halting problem
&lt;/h1&gt;

&lt;p&gt;Imagine I am your product manager, you work for a company that builds tools that debug programs. I ask you, can you produce me a program that will tell me if a given piece of code will eventually stop executing. We'll also assume for this use case that we're ignoring programs that do I/O. The world of I/O is messy, and we're mostly concerned with computation bugs. We'll call programs that terminate "halting".&lt;/p&gt;

&lt;p&gt;Well, you might intuitively start with some unit tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def test_halts?
  expect(halts?("1+1")).to be true
  expect(halts?("while true; end")).to be false
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A program that just adds 1 and 1 together clearly halts executing, almost immediately in fact. A program that loops forever clearly does not. This problem &lt;strong&gt;is&lt;/strong&gt; well defined. Consume a program and check if it stops. This is similar to the JSON parsing case, in that we can express this to a computer in a very unambiguous day. Let’s look at why we can’t solve this.&lt;/p&gt;

&lt;p&gt;Now, we could trivially knock out an implementation of &lt;code&gt;halts?&lt;/code&gt; that works for the two inputs above. But what about more complicated cases? What about mapping over an array, what about conditionals that contain loops? What about complex nested while loops with twisty recursive logic? You may be thinking “I could probably knock out solutions to this on a case by case basis, and eventually cover everything. Certainly, you could cover &lt;em&gt;some&lt;/em&gt; programs by doing this, but dear reader, it turns out that building &lt;code&gt;halts?&lt;/code&gt; in the generic case is quite impossible.&lt;/p&gt;

&lt;h1&gt;
  
  
  You can't solve this problem
&lt;/h1&gt;

&lt;p&gt;It turns out, this problem is quite unsolvable. The formal proof for this is very complicated, but the intuitive proof can be shown in just a few lines of code. Let's &lt;strong&gt;imagine&lt;/strong&gt; we have already written the &lt;code&gt;halts?&lt;/code&gt; function. With that consider the following case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def do_the_opposite
  # here we are passing this function, “do_the_opposite”
  # to halts?, effectively asking it halts? whether or not
  # do_the_opposite ever finishes executing.
  if halts?(“do_the_opposite”)
    while true
    end
  else
    exit
  end  
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What we're saying is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;if &lt;code&gt;halts?&lt;/code&gt; thinks &lt;code&gt;do_the_opposite&lt;/code&gt; halts, then &lt;code&gt;do_the_opposite&lt;/code&gt; loops forever&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;halts?&lt;/code&gt; thinks &lt;code&gt;do_the_opposite&lt;/code&gt; executes forever then &lt;code&gt;do_the_opposite&lt;/code&gt; exits immediately.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This catches the &lt;code&gt;halts?&lt;/code&gt; function in a contradiction, it &lt;em&gt;must&lt;/em&gt; be wrong. In other words: we can't define a function which accurately tells us if all programs finish executing. This is the definition of a proof by contradiction. The existence of the &lt;code&gt;halts?&lt;/code&gt; function implies a logically impossible universe exists.&lt;/p&gt;

&lt;p&gt;Why is this interesting? Well, it more broadly tells us that despite all the power of our modern programming languages, powerful type systems, etc, there are still some problems we can't solve. It also tells us that a bunch of problems that we can't solve are related to the code we work on itself. If you're interested in learning more about exactly what the halting problem says, you can find out more by reading about the &lt;a href="https://plato.stanford.edu/entries/church-turing/"&gt;church-turing thesis&lt;/a&gt;&lt;/p&gt;

</description>
      <category>computerscience</category>
    </item>
    <item>
      <title>Penelope: Nevertheless, She</title>
      <dc:creator>Penelope Phippen</dc:creator>
      <pubDate>Sat, 07 Mar 2020 14:30:44 +0000</pubDate>
      <link>https://dev.to/penelope_zone/penelope-nevertheless-she-2fd3</link>
      <guid>https://dev.to/penelope_zone/penelope-nevertheless-she-2fd3</guid>
      <description>&lt;p&gt;Hi Penelope,&lt;/p&gt;

&lt;p&gt;You're new to this. It certainly feels strange to be writing a letter to yourself on International Women's Day. But you can't help but smile reading that. Yourself, International Women's Day.&lt;/p&gt;

&lt;p&gt;This is a space that's new for you. To be celebrating yourself with other women. And you should be mindful of that. You've come here through a very different path than all the cis women, and many of the trans women and non-binary folks who also got here. You've gone the majority of your career enjoying male privilege. You've started to see some of that privilege fade away, as the world interprets you as more feminine. Gosh it's annoying to be interrupted and spoken over by a man who has no idea what he's saying. Some of that privilege, however, comes from inside and will always be a part of you. So this is a time to listen, as much as it is a time for you to speak.&lt;/p&gt;

&lt;p&gt;That isn't to say you shouldn't be here, celebrating, with all the other women in technology. Transition is hard. Say that to yourself one more time. Transition. Is. Hard. Just yesterday, on Friday, one of your colleagues misgendered you, unintentionally, and he quickly apologized, but that's a paper cut. A paper cut that still stings every time. A sting that you'll feel many more times. This is one of many thousands of ways that you'll be reminded you're different. Reminders that will follow you for the rest of your career. It's something that'll never really disappear.&lt;/p&gt;

&lt;p&gt;Neither, though, need your difference disappear. You are an unmitigated badass, you've worked on projects that have literally defined the direction of the Ruby community. You're the program chair for the largest conference in the community that gave you all the success and love you could have ever asked for. You're working on something new, that has the potential to reshape the way people work with the Ruby programming language, and it's bringing you so much happiness.&lt;/p&gt;

&lt;p&gt;You get to be a woman now, and you get to define what it means for you. You've already seen amazing things sprout because of it, and you know there are more to come. It's not going to be easy, and the change that's coming will bring much hardship along the way. But you know it's worth it. You know it's worth spending the time to work out how to be you. Really, to be yourself, for the first time in your adult life.&lt;/p&gt;

&lt;p&gt;The slogan for this post is "Nevertheless, She Coded,” but here's the thing. For you, the code comes easy. It always has and it probably always will. Your closest friends and peers have commented that your technical strength is scary and impressive, and that some of them are a little bit jealous. For you, it'll be everything else, this new life around the code that'll be hard. So perhaps, instead of "Nevertheless, She Coded" right now you just need to celebrate, yourself: Nevertheless, She.&lt;/p&gt;

</description>
      <category>wecoded</category>
    </item>
    <item>
      <title>Understanding Ruby's block/proc parsing</title>
      <dc:creator>Penelope Phippen</dc:creator>
      <pubDate>Sat, 22 Feb 2020 16:45:54 +0000</pubDate>
      <link>https://dev.to/penelope_zone/understanding-ruby-s-block-proc-parsing-4a89</link>
      <guid>https://dev.to/penelope_zone/understanding-ruby-s-block-proc-parsing-4a89</guid>
      <description>&lt;p&gt;In Ruby, methods can take a single block as an argument, which can be specified explicitly in the method signature by writing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;some_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;blk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;or implicitly in the method body by writing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;some_method&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;block_given?&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are a few ways of specifying the block to the method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;some_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;blk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;blk&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;some_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:foo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;some_method&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;foo&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;some_method&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;These are all (roughly) equivalent, calling the &lt;code&gt;foo&lt;/code&gt; method in the place of the passed &lt;code&gt;blk&lt;/code&gt; parameter. How they are parsed, however, is very different:&lt;/p&gt;

&lt;h2&gt;
  
  
  Passing an expression with &lt;code&gt;&amp;amp;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Imagine we call this method as: &lt;code&gt;some_method(&amp;amp;:foo)&lt;/code&gt;. The parse tree looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:program&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="ss"&gt;:method_add_arg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:fcall&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:@ident&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"some_method"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]]],&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:arg_paren&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:args_add_block&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="p"&gt;[],&lt;/span&gt;
     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:symbol_literal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:@ident&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;]]]]]]]]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Specifically, the argument structure to the call is parsed as a parser node called &lt;code&gt;args_add_block&lt;/code&gt;, which contains an expression list (that's the empty array in the code example above), and a single expression at the end (that's the &lt;code&gt;:symbol_literal&lt;/code&gt; expression that represents the to_proc expression). The first expression list is the non proc arguments to the call.&lt;/p&gt;

&lt;h1&gt;
  
  
  Passing a block
&lt;/h1&gt;

&lt;p&gt;Imagine we call the method as: &lt;code&gt;some_method { foo }&lt;/code&gt;. The parse tree looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:program&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="ss"&gt;:method_add_block&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:method_add_arg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:fcall&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:@ident&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"some_method"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]]],&lt;/span&gt; &lt;span class="p"&gt;[]],&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:brace_block&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="ss"&gt;:vcall&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:@ident&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;]]]]]]]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in particular, note that we &lt;em&gt;no longer&lt;/em&gt; have an &lt;code&gt;args_add_block&lt;/code&gt; parse node. This is because in this style of call, the block is not treated as part of the arguments to the call by the parser, instead, it is treated as a modifier to the method call, that changes &lt;em&gt;which call type&lt;/em&gt; is being made. &lt;/p&gt;

&lt;h2&gt;
  
  
  why did you write this?
&lt;/h2&gt;

&lt;p&gt;This acts as documentation for the ongoing development of &lt;a href="https://github.com/penelopezone/rubyfmt"&gt;Rubyfmt&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>parsers</category>
    </item>
    <item>
      <title>Changing your name is a hard unsolved problem in Computer Science
</title>
      <dc:creator>Penelope Phippen</dc:creator>
      <pubDate>Fri, 03 Jan 2020 14:35:42 +0000</pubDate>
      <link>https://dev.to/penelope_zone/changing-your-name-is-a-hard-unsolved-problem-in-computer-science-kjf</link>
      <guid>https://dev.to/penelope_zone/changing-your-name-is-a-hard-unsolved-problem-in-computer-science-kjf</guid>
      <description>&lt;p&gt;The nerdy joke is that there are only 2 hard problems in computer science:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Naming things&lt;/li&gt;
&lt;li&gt;Cache invalidation&lt;/li&gt;
&lt;li&gt;Off by one errors&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I've recently had the interesting experience of changing my name. I have my name: the one I use on a daily basis, the one I identify with, the one to which I actually respond. I also have the name I was born under, or my "deadname" in the colloquial trans parlance. I don’t really identify with this name any more, but it follows me around like a spectre haunting Europe. There's now a noticeable gap between me hearing my deadname and realising someone's referring to me. It's fun to see how quickly those things change.&lt;/p&gt;

&lt;p&gt;So, this brings me to my primary conceit for this post. We, as an industry, are &lt;em&gt;horrible&lt;/em&gt; at accepting name changes for folks. In this post I'll give some examples of things I've seen done wrong. I'll show you how you can make your application better for folks who are changing their name. Let’s dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  Google accounts, and single sign-on
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer, I work for Google. This section is my opinion and my best understanding, and does not represent the opinions, or views of Google LLC, or Alphabet Inc. In my opinion Google has done a lot to make changing one’s name easy, which I really appreciate, but some folks using Google APIs don't do the best integration here&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are two types of Google accounts, individual, and GSuite Google's business offering. Each Google account has one primary email address, and zero or more aliases associated with it. The most important thing to know is that the primary email address can change &lt;strong&gt;on the same account&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So if you're &lt;a href="mailto:alice@somegsuitedomain.com"&gt;alice@somegsuitedomain.com&lt;/a&gt;, you can become &lt;a href="mailto:bob@somegsuitedomain.com"&gt;bob@somegsuitedomain.com&lt;/a&gt;. When you do that you keep your account, inbox, and all your Google apps access under the same account. Under the hood there's a stable identifier that's associated with the account that does not change when the email address changes. &lt;strong&gt;In other words, an email address is not the primary key of a Google account&lt;/strong&gt;. When you change your Google email address, Google sets up a permanent, undeletable, alias for the old email address. This means if you send an email to the old address, the person will receive it. However, I suspect if you ask most folks, they'd tell you they don't want to see it.&lt;/p&gt;

&lt;p&gt;If your application implements single sign-on with Google, you should key off the stable ID, and not the email adress or name. if you store the email and name in your database, you should change them if Google tells you they has changed.&lt;/p&gt;

&lt;p&gt;Let's look at the mechanics of how you can implement this with Google's OAuth APIs. I set up the basic &lt;a href="https://github.com/zquestz/omniauth-google-oauth2"&gt;OAuth workflow&lt;/a&gt; in Rails, and the first details that came back from my account were (partially redacted):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"provider"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"google"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"uid"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"113017XXXXXXXX8346486"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"info"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"Penelope Phippen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"email"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"penelope@rubycentral.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"unverified_email"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"penelope@rubycentral.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"email_verified"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"first_name"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"Penelope"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"last_name"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"Phippen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"image"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"https://lh3.googleusercontent.com/-Tj-GuDdntsY/AAAAAAAAAAI/AAAAAAAAAAA/ACHi3rfGmAsSR_4ZenyOeMkId6EERxmFIg/s50-c/photo.jpg"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, it's worth noting, the email address associated with this account used to be different. Every time you do an OAuth exchange with this account, it'll give you the new email address and name. So, the right thing to do here is &lt;em&gt;update your user record&lt;/em&gt; with the new email address and name every time you get a new OAuth payload back. If a user's name has changed, you can assume it's intentional, and update from that. The thing that will always be stable is the &lt;code&gt;uid&lt;/code&gt; field, which &lt;a href="https://www.oauth.com/oauth2-servers/signing-in-with-google/verifying-the-user-info/"&gt;actually comes from the &lt;code&gt;sub&lt;/code&gt; field&lt;/a&gt; in the raw OAuth response.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let me change my username, you cowards.
&lt;/h2&gt;

&lt;p&gt;The next is the family of applications which have their own auth. Before email became the standard way to identify users, we had the username. Many applications have long since migrated off letting users specify usernames. Those apps are now authenticating only with email address.&lt;/p&gt;

&lt;p&gt;I've found that certain applications don't let you change your username. I used my deadname as my primary internet identifier up until I changed my name. &lt;strong&gt;If I can't change my username, and I've accumulated significant data on your application, I don't want to have to destroy my account and start a new one&lt;/strong&gt;. This puts me in a place where your application is repeatedly deadnaming me, and I can't do anything about it. Build in fungibility of your usernames, let folks change them. Please for the love of all that is holy don't use a user provided string as a primary database key. &lt;/p&gt;

&lt;h2&gt;
  
  
  Don't allow for username re-use
&lt;/h2&gt;

&lt;p&gt;This one is a security/harassment vehicle. On websites like &lt;a href="https://github.com"&gt;GitHub&lt;/a&gt; and &lt;a href="https://twitter.com"&gt;Twitter&lt;/a&gt;, you &lt;strong&gt;can&lt;/strong&gt; change the username associated with your account, which is great. However, this introduces a new problem, what to do with the old username?&lt;/p&gt;

&lt;p&gt;Both GitHub and Twitter allow for a username to be registered the moment that you change your old username. On Twitter, this means that when a person changes their username, you could immediately impersonate their old identity. On GitHub, this means that if people are pulling software from your old name, someone could immediately replace your repos with malware. &lt;/p&gt;

&lt;p&gt;On both sites, I now have "squatter" accounts, that hold my old name. This is largely a security protection for myself and those who follow my work. I've written more than one pretty popular software package. People could plausibly be git cloning those packages as their dependency management strategy (please don't do this). It's worth noting GitHub does set up redirects &lt;strong&gt;until&lt;/strong&gt; someone with the same username creates a repo with the same name, but a targeted attack would be almost trivial to pull off. On Twitter, I didn't want a troll occupying my old name and pretending to be me.&lt;/p&gt;

&lt;p&gt;Here's the thing, almost certainly, re-using a username is something that you &lt;strong&gt;never&lt;/strong&gt; want to have happen. Unless there's literally 0 security or harassment opportunity with your application, letting someone else occupy someone's old name is going to result in problems. The right thing to do is, most likely, just redirect everything under the old name to the new name, and not let anybody else interact with data on the old name.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caching name off other identifiers
&lt;/h2&gt;

&lt;p&gt;I first encountered this one in real life in a virtual queueing system for a restaurant. They asked me for my name, I said "Penelope'", then they asked me for my phone number. Dutifully, I gave them my phone number (which hasn't changed since I moved to the US). Then when they texted me to tell me my table was ready the text contained my deadname. Annoying, but NBD I thought. Then when I got back to the restaurant, my friends and I were treated to being told our table for [my deadname] was ready.&lt;/p&gt;

&lt;p&gt;What's upsetting about this interaction is that I had given them my name. Whatever virtual queuing system had grabbed my name from some previous interaction with it, and then not properly invalidated it when I gave them my new name. As far as I can tell, having backtracked through their website there's no way for me to manually change my name in their system. So I expect I will just continue to get deadnamed by this system for the rest of my life. My other choice is to change my phone number, which is obviously annoying.&lt;/p&gt;

&lt;p&gt;The lesson here is that names are fungible in relation to other identifiers. In the case of phone numbers, well, they can get recycled. A phone number belonging to only one person for an extended period of time is the exception and not the rule. In my case, this naïve exception has resulted in my life now containing additional annoying and upsetting interactions.&lt;/p&gt;

&lt;h2&gt;
  
  
  You don't even have to use my legal name for most things
&lt;/h2&gt;

&lt;p&gt;Now we come to the section of interactions where using my legal name is an admitted requirement. If you're a government organisation, financial institution, or other similar body, I understand the need for your company to know my legal name. That's fine, I'll be changing it soon, but in the meantime, I'd like to point out that you don't need to use it all the time. &lt;/p&gt;

&lt;p&gt;To use an example, let's think about one of the investing applications I use. When I set up my account, they took my full legal name, to verify my identity. Ever since, they've emailed me using that name. Even before I changed my name, I didn't use my full legal name for most things. I used a short version. It feels weird and overly formal that all their product emails are addressed to my legal name. I can't set a different name with them. Now that I've changed my name, things reveal my legal name that absolutely 100% don't need to.  A simple statement doesn't need to use my legal name. From their perspective, there's no difference between &lt;code&gt;Hey &amp;lt;legal deadname&amp;gt;, here's your balance&lt;/code&gt; and &lt;code&gt;Hey Penelope, here's your balance&lt;/code&gt;. Unlike a bank statement, those emails can't be used for proof of address or similar so they don't need to be so formal.&lt;/p&gt;

&lt;p&gt;I’d also like to point out that legal names can change. Changing my non-legal name has been enough of a battle with tech companies as it is, I’ll be sure to detail all the things that are needed to get that legal name change everywhere in a future post. In the meantime, see if you can do some work to make it easier for folks to change how you address them in your apps.&lt;/p&gt;

&lt;p&gt;A more extreme example of my legal name being used unnecessarily is when I'm talking with my credit card companies on the phone. They only know me by my legal identity, but it'd be vastly more comfortable for me if I could use a different name and honorific on the phone (&lt;code&gt;miss&lt;/code&gt; instead of &lt;code&gt;sir&lt;/code&gt;). Again, in that context there's no impact to them for doing so, but there is a huge impact on me. It's also not the sort of thing where I feel ok just being like &lt;br&gt;
“Hey, this seems kind of weird, but could you refer to me as Miss Phippen instead”. If your application does require a legal name, please consider having fields for preferred name, pronouns, and honorific that your staff/communications can use to address folks most of the time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;This post hasn't even covered all the ways that you, dear reader, likely have no power to make name changes. OS X and Windows both burn your username into the OS install in such a way that you need to reinstall to ever get properly rid of it. There's a constellation of things that will probably always bare the wrong name for me. This post gives a few practical tips for fixing that, however. And I hope you can do a little to make it easier for all of us, in the locus of control you do have. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consider this my ask to you, that if you’re working on a product that involves using someone’s name, pronouns, or honorifics, that you make it easy to change in a self service manner. This is a basic dignity for many folks, and it’d mean a lot to me.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm coming to this from the perspective of someone who's trans, who has changed their first name to signal a significant change in who I am. This isn't the only reason someone changes their name (see also: marriage, parents getting divorced, and myriad other reasons), but my use case has thus far worked as something of a stress test for various computer systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For all people, there is an essential dignity to living our lives being identified as we want to be&lt;/strong&gt;. As you develop your computer systems, please keep the following things in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A person's name can change (and with a pretty high probability, will) once or more in their life&lt;/li&gt;
&lt;li&gt;A person will want to change multiple identifiers when that happens including email addresses and usernames&lt;/li&gt;
&lt;li&gt;if your application doesn't allow for that, the person might experience significant pain or distress because of that inflexibility&lt;/li&gt;
&lt;li&gt;A legal name is something that someone may wish to be not associated with frequently, and you should allow folks to give you another name against which to refer to them and then use that most of the time&lt;/li&gt;
&lt;li&gt;If you want to make your application more friendly to a wider set of humans you should support making those changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you so much for reading. If you liked this, please consider following me on twitter &lt;a href="https://twitter.com/penelope_zone"&gt;@penelope_zone&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>A silly thing you can do with the Ruby parser</title>
      <dc:creator>Penelope Phippen</dc:creator>
      <pubDate>Sun, 22 Dec 2019 13:12:52 +0000</pubDate>
      <link>https://dev.to/penelope_zone/a-silly-thing-you-can-do-with-the-ruby-parser-557n</link>
      <guid>https://dev.to/penelope_zone/a-silly-thing-you-can-do-with-the-ruby-parser-557n</guid>
      <description>&lt;p&gt;Here's a silly thing you can do with the Ruby parser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;begin&lt;/span&gt;
  &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s2"&gt;"omg"&lt;/span&gt;
&lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Box&lt;/span&gt;
   &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
     &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:contents&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="no"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;contents&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contents&lt;/span&gt;

&lt;span class="c1"&gt;# =&amp;gt; "omg"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  You... what?
&lt;/h2&gt;

&lt;p&gt;So let's break this down. In Ruby, the way one catches exceptions is with a&lt;br&gt;
&lt;code&gt;begin...rescue...end&lt;/code&gt; expression. The &lt;code&gt;rescue&lt;/code&gt; part of that looks like this:&lt;br&gt;
&lt;code&gt;rescue &amp;lt;class_name&amp;gt; =&amp;gt; &amp;lt;assignable_expression&amp;gt;&lt;/code&gt;. Usually you'd see something&lt;br&gt;
like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;begin&lt;/span&gt;
 &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="n"&gt;whatever&lt;/span&gt;
&lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;SomeClass&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;some_local_variable_name&lt;/span&gt;
  &lt;span class="n"&gt;do_something_with_local_variable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;some_local_variable_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, it doesn't have to be this way. In fact, the Ruby parser permits any&lt;br&gt;
valid assignment expression in Ruby! So we can for example set a key in a hash&lt;br&gt;
from a rescue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="k"&gt;begin&lt;/span&gt;
  &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s2"&gt;"omg"&lt;/span&gt;
&lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:the_key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inspect&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; {:the_key=&amp;gt;#&amp;lt;RuntimeError: omg&amp;gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, to come back to our first example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;begin&lt;/span&gt;
  &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s2"&gt;"omg"&lt;/span&gt;
&lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Box&lt;/span&gt;
   &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
     &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:contents&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="no"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;contents&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contents&lt;/span&gt;

&lt;span class="c1"&gt;# =&amp;gt; "omg"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we, &lt;strong&gt;in the rescue clause&lt;/strong&gt;, define a class called box, define a class&lt;br&gt;
level attribute called contents, and then set it. You shouldn't ever do this in&lt;br&gt;
you production code, but it is possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is this even possible?
&lt;/h2&gt;

&lt;p&gt;As far as I can tell, the reason why this works as it does has to do with the&lt;br&gt;
history of the implementation of Ruby. Before Ruby 1.9, Ruby used a "tree&lt;br&gt;
walking" interpreter. This means that Ruby code was executed from the syntax&lt;br&gt;
tree of the program, with no intermediate steps. Putting the rescued exception&lt;br&gt;
"somewhere", conceptually, is the same thing as variable assignment, even though&lt;br&gt;
it doesn't look like &lt;code&gt;local_name =&lt;/code&gt;, so the code was shared between rescue and&lt;br&gt;
variable assignment.&lt;/p&gt;

&lt;p&gt;Neat!&lt;/p&gt;

&lt;p&gt;If you enjoyed this post, please consider sending me a follow on twitter:&lt;br&gt;
&lt;a href="https://twitter.com/penelope_zone"&gt;@penelope_zone&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ruby</category>
    </item>
  </channel>
</rss>
