<?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: Kat Padilla</title>
    <description>The latest articles on DEV Community by Kat Padilla (@katpadi).</description>
    <link>https://dev.to/katpadi</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%2F2012%2FSSZRbdPF.jpg</url>
      <title>DEV Community: Kat Padilla</title>
      <link>https://dev.to/katpadi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/katpadi"/>
    <language>en</language>
    <item>
      <title>Handling Errors Gracefully</title>
      <dc:creator>Kat Padilla</dc:creator>
      <pubDate>Thu, 05 Apr 2018 15:09:36 +0000</pubDate>
      <link>https://dev.to/katpadi/handling-errors-gracefully-2ced</link>
      <guid>https://dev.to/katpadi/handling-errors-gracefully-2ced</guid>
      <description>

&lt;p&gt;Sometimes it makes sense to treat errors as part of an application's "valid" flow of events. Meaning, expected errors should not necessarily make your code go crazy when random errors are raised.&lt;/p&gt;

&lt;p&gt;With that in mind, I created a way to implement some kind of "Result Object" by rescuing &lt;a href="https://ruby-doc.org/core-2.1.5/StandardError.html"&gt;StandardError&lt;/a&gt; instances and handling these errors gracefully.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Gracefully
  class &amp;lt;&amp;lt; self
    alias_method :handle, :new
  end

  attr_reader :error, :value

  def initialize
    @value = nil
    @error = nil
    begin
      @value = yield
    rescue =&amp;gt; e
      @error = e
    end
  end

  def success?
    error.nil?
  end

  def on_success
    return self unless success?
    result = yield(@value)
    return result if result.is_a?(Gracefully)
    Gracefully.handle { result }
  end

  def on_failure
    return self if success?
    result = yield(@error)
    return result if result.is_a?(Gracefully)
    Gracefully.handle { result }
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;a href="https://gist.github.com/9aac974a760fc3f5f3a287bb75804de6"&gt;gracefully.rb&lt;/a&gt; &lt;a href="https://gist.githubusercontent.com/katpadi/9aac974a760fc3f5f3a287bb75804de6/raw/f2286a1645a66f7867db9abbd9ebf95113e46da3/gracefully.rb"&gt;view raw&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;In short, _ &lt;strong&gt;Gracefully&lt;/strong&gt; _ is a wrapper for a result object– it’s either a success value or an error object.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;result = Gracefully.handle { Order.find 999 }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the example above, if order with id 999 does not exist, &lt;strong&gt;&lt;em&gt;result.success?&lt;/em&gt;&lt;/strong&gt; method will return false. Otherwise, true.&lt;/p&gt;

&lt;p&gt;If &lt;strong&gt;&lt;em&gt;result.success?&lt;/em&gt;&lt;/strong&gt;is true, &lt;em&gt;&lt;strong&gt;result.value&lt;/strong&gt;&lt;/em&gt; will contain the successful value. Otherwise, &lt;em&gt;&lt;strong&gt;result.error&lt;/strong&gt;&lt;/em&gt; will hold the error object itself.&lt;/p&gt;

&lt;p&gt;Whenever Gracefully.handle is called, it will return a Gracefully object. If you want to get the raw value, you can use &lt;em&gt;&lt;strong&gt;result.value&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  More Usage
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;result = Gracefully.handle { ComplicatedService.new(foo, bar).process }
if result.success?
  # do success stuff
  use_value(result.value)
else
  # do failure stuff
  log_error(result.error)
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Chaining Usage
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Gracefully.handle { SomeComplicatedService.new.call }.on_success do |val|
  val.update!(column_name: 'stuff')
end

Gracefully.handle { SomeComplicatedService.new.call }.on_failure do |e|
  do_whatever_you_wish_with_the_error(e)
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;By using this, I can be resilient in handling errors and be able to recover from failures in the process flow.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="http://blog.katpadi.ph/handling-error-gracefully/"&gt;Handling Errors Gracefully&lt;/a&gt; appeared first on &lt;a href="http://blog.katpadi.ph"&gt;KatPadi's Point&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;--&lt;br&gt;
Visit my website @ &lt;a href="http://katpadi.ph"&gt;http://katpadi.ph&lt;/a&gt;.&lt;/p&gt;


</description>
      <category>codes</category>
      <category>errors</category>
      <category>resultobject</category>
      <category>ruby</category>
    </item>
    <item>
      <title>What audiobook did you last listen to?</title>
      <dc:creator>Kat Padilla</dc:creator>
      <pubDate>Tue, 20 Mar 2018 12:14:58 +0000</pubDate>
      <link>https://dev.to/katpadi/what-audiobook-did-you-last-listen-to-460b</link>
      <guid>https://dev.to/katpadi/what-audiobook-did-you-last-listen-to-460b</guid>
      <description>&lt;p&gt;I listened to &lt;a href="https://www.audible.com/pd/Sci-Fi-Fantasy/The-Dispatcher-Audiobook/B01KKPH1VA"&gt;The Dispatcher&lt;/a&gt; by John Scalzi and it was awesome. My thoughts are &lt;a href="http://blog.katpadi.ph/listened-dispatcher-awesome/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What did you last listen to? &lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Hi, I'm katpadi</title>
      <dc:creator>Kat Padilla</dc:creator>
      <pubDate>Wed, 18 Jan 2017 03:52:16 +0000</pubDate>
      <link>https://dev.to/katpadi/hi-im-katpadi</link>
      <guid>https://dev.to/katpadi/hi-im-katpadi</guid>
      <description>&lt;p&gt;I have been coding for ~7 years.&lt;/p&gt;

&lt;p&gt;You can find me on Twitter as &lt;a href="https://twitter.com/katpadi" rel="noopener noreferrer"&gt;@katpadi&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I live in Manila at the moment.&lt;/p&gt;

&lt;p&gt;I work for a software company that helps brands increase their customer loyalty and engagement. &lt;/p&gt;

&lt;p&gt;I mostly program in Ruby currently. I used to write PHP. I am also a bit functional with Python. &lt;/p&gt;

&lt;p&gt;Nice to meet you.&lt;/p&gt;

</description>
      <category>introduction</category>
    </item>
    <item>
      <title>TIL: Redis Keyspace Notifications</title>
      <dc:creator>Kat Padilla</dc:creator>
      <pubDate>Thu, 12 Jan 2017 11:00:00 +0000</pubDate>
      <link>https://dev.to/katpadi/til-redis-keyspace-notifications-3eca</link>
      <guid>https://dev.to/katpadi/til-redis-keyspace-notifications-3eca</guid>
      <description>&lt;p&gt;For some reason, I was figuring out a way to be able to listen to Redis so I can fire callbacks when the Redis command or event  is encountered.&lt;/p&gt;

&lt;p&gt;I wanted to do something like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;*&lt;em&gt;When a key gets removed from the sorted set, it will trigger a script that will notify a user. *&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Browsing online, I came across the so-called &lt;a href="https://redis.io/topics/notifications" rel="noopener noreferrer"&gt;&lt;strong&gt;Redis Keyspace Notifications&lt;/strong&gt;&lt;/a&gt;. It basically acts as a Pub/Sub mechanism that enables clients to subscribe to a Redis channel and receive “published” events whenever a Redis command or data alteration is encountered. The feature is available since version 2.8, apparently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diving in…
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi1.wp.com%2Fblog.katpadi.ph%2Fwp-content%2Fuploads%2F2017%2F01%2F1.1282587206.mark-diving-in.jpg%3Fresize%3D491%252C369" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi1.wp.com%2Fblog.katpadi.ph%2Fwp-content%2Fuploads%2F2017%2F01%2F1.1282587206.mark-diving-in.jpg%3Fresize%3D491%252C369" alt="Literally a person who is diving in. LOL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Literally a person who is diving in. LOL&lt;/p&gt;

&lt;p&gt;The said notifications are enabled using the &lt;code&gt;notify-keyspace-events&lt;/code&gt; of redis.conf or via the &lt;strong&gt;CONFIG SET&lt;/strong&gt;. It is disabled by default.&lt;/p&gt;

&lt;p&gt;Setup will look something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Set it up.
$redis.config(:set, 'notify-keyspace-events', 'zE')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://gist.github.com/2eca03737eb188707cc79e9969185eee" rel="noopener noreferrer"&gt;redis-kesypace-event.rb&lt;/a&gt; &lt;a href="https://gist.githubusercontent.com/katpadi/2eca03737eb188707cc79e9969185eee/raw/213a4d7f0f2055ed2853ba3997b382d9da9ec61d/redis-kesypace-event.rb" rel="noopener noreferrer"&gt;view raw&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  zE… wut???
&lt;/h2&gt;

&lt;p&gt;zE looks so random if you weren’t briefed that each character in that string has a meaning.&lt;/p&gt;

&lt;p&gt;Below is the list of variable mapping for keyspace events:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi1.wp.com%2Fblog.katpadi.ph%2Fwp-content%2Fuploads%2F2017%2F01%2FScreen-Shot-2017-01-12-at-6.48.57-PM.png%3Fresize%3D752%252C294" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi1.wp.com%2Fblog.katpadi.ph%2Fwp-content%2Fuploads%2F2017%2F01%2FScreen-Shot-2017-01-12-at-6.48.57-PM.png%3Fresize%3D752%252C294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For my particular case, I needed to use “&lt;code&gt;zE&lt;/code&gt;” string because I want to catch the name of the key (and not the name of the event) when &lt;code&gt;zrem&lt;/code&gt;, which is a sorted set command, is encountered.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keyspace v.s. Keyevent
&lt;/h2&gt;

&lt;p&gt;Let’s cut to the chase! Use keyspace if you want to receive the &lt;strong&gt;name of the event&lt;/strong&gt;. Use keyevent if you want to receive the &lt;strong&gt;name of the key&lt;/strong&gt;.&lt;/p&gt;

&lt;h6&gt;
  
  
  &lt;em&gt;TILception (TIL within a TIL): If you want to enable all events, use “KEA”.&lt;/em&gt;
&lt;/h6&gt;

&lt;p&gt;So, here’s an example of what I played around with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Subscriber
$redis.psubscribe(' __keyevent@*__ :zrem') do |on|
  on.pmessage do |pattern, channel, message|
    puts "==== AFTER zrem EVENT ====="
    # Available things:
    puts "pattern: #{pattern}"
    puts "channel: #{channel}"
    puts "message: #{message}"
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://gist.github.com/2eca03737eb188707cc79e9969185eee" rel="noopener noreferrer"&gt;redis-kesypace-event.rb&lt;/a&gt; &lt;a href="https://gist.githubusercontent.com/katpadi/2eca03737eb188707cc79e9969185eee/raw/213a4d7f0f2055ed2853ba3997b382d9da9ec61d/redis-kesypace-event.rb" rel="noopener noreferrer"&gt;view raw&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;As I told earlier, I wanted to catch the “key” as a message and not the “event”. So, the message variable in the above code will output the key.&lt;/p&gt;

&lt;p&gt;Now, in your redis-cli, if you try to prepare a sorted set by using &lt;code&gt;zadd&lt;/code&gt; and then doing a &lt;code&gt;zrem&lt;/code&gt;, you will see the output in your console.&lt;/p&gt;

&lt;p&gt;=)&lt;/p&gt;

&lt;p&gt;Now it’s time for me to send that notification!&lt;/p&gt;

&lt;p&gt;The post &lt;a href="http://blog.katpadi.ph/til-redis-keyspace-notifications/" rel="noopener noreferrer"&gt;TIL: Redis Keyspace Notifications&lt;/a&gt; appeared first on &lt;a href="http://blog.katpadi.ph" rel="noopener noreferrer"&gt;KatPadi's Point&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>codes</category>
      <category>tech</category>
      <category>thoughts</category>
      <category>rediscallback</category>
    </item>
    <item>
      <title>Git: Squash Commits</title>
      <dc:creator>Kat Padilla</dc:creator>
      <pubDate>Mon, 12 Dec 2016 10:52:14 +0000</pubDate>
      <link>https://dev.to/katpadi/git-squash-commits-48c6</link>
      <guid>https://dev.to/katpadi/git-squash-commits-48c6</guid>
      <description>&lt;p&gt;With git it’s possible to &lt;a href="https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History" rel="noopener noreferrer"&gt;squash&lt;/a&gt; previous commits into one before sharing them with others.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1
&lt;/h2&gt;

&lt;p&gt;For example you want to squash your last 3 commits:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git rebase -i HEAD~3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;On the other hand, if you want to just simply squash all the unpushed commits:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git rebase -i origin/master&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you have many commits and want to start from a certain commit:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git rebase -i&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Any of the command above will prompt open your editor with something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pick a92f09 Added new feature X
pick ca9f90a Some other stuff I did
pick d18a6h1 More stuff I did
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will show up in your editor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pick a92f09 Added new feature X
squash ca9f90a Some other stuff I did
squash d18a6h1 More stuff I did
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: If you don’t have an editor defined in your config, you will encounter &lt;code&gt;Could not execute editor&lt;/code&gt;. Just do &lt;code&gt;git config --global core.editor /usr/bin/vim&lt;/code&gt; for you to be able to proceed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2
&lt;/h2&gt;

&lt;p&gt;Next, we can configure git on what to do with the commits. Let’s say, I want to keep commit a92f09. Git squash-ing the following two commits into the first one will leave us with one single commit with all the commits in it. To do that, change your file to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pick a92f09 Added new feature X
squash ca9f90a Some other stuff I did
squash d18a6h1 More stuff I did
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and exit.&lt;/p&gt;

&lt;p&gt;That’s it. Git squash is especially useful if you want to wrap up “all in a day’s work” or if you want to have a clean and concise git history.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Use &lt;code&gt;git rebase -i origin/master&lt;/code&gt; and replace “pick” on the second and succeeding commits with “squash”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi1.wp.com%2Fblog.katpadi.ph%2Fwp-content%2Fuploads%2F2016%2F12%2Ftemp_quash.jpg%3Fresize%3D267%252C178" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi1.wp.com%2Fblog.katpadi.ph%2Fwp-content%2Fuploads%2F2016%2F12%2Ftemp_quash.jpg%3Fresize%3D267%252C178" alt="git squash?"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post &lt;a href="http://blog.katpadi.ph/git-squash/" rel="noopener noreferrer"&gt;Git: Squash Commits&lt;/a&gt; appeared first on &lt;a href="http://blog.katpadi.ph" rel="noopener noreferrer"&gt;KatPadi's Point&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>myworklog</category>
      <category>git</category>
      <category>gitrebase</category>
      <category>gitsquash</category>
    </item>
  </channel>
</rss>
