kinopyo blog

Learning through Writing

4 Thoughtful Quotes That Saved My Day

I had a bad day, I'm having bad days. I'm writing journals everyday, which is supposed to be a place for self realizations but instead nowadays I'm more like dumping my stress, depressions or even angers there.

With all that, today was different, some "magic" happened.

I picked up a book in a bookstore, I opened it, just one single phrase in the first page, and it goes:

Always look at the bright side of life - Monty Python

I don't know why it strikes me like a thunder. I'm sure I'll just skip it in any of my "ordinary" days but, it has the power to turn me to look at literally the bright side of things I've been going through. Indeed it's bright, more than bright, those are great things, it just comes equally with a price. Don't forget the vision, don't forget the bright side that brings you here in the first place, that's the message, don't know how much I appreciate it and the book.

Then, a second one kicks in later. I heard it a while ago from an evangelist at a local church, I don't believe in god but it still resonates with me.

All the things you've been going through, they're all under god's plan, you just haven't understood the reason yet.

(Originally it was in Japanese: "今までの全てはきっと神様のご計画通りで、我々はただまだそれを理解していないだけ"

Let me show you the 3rd quote now, it's very similar to the 2nd one:

Things don't happen to you, they happen for you

Yes, they happen for me, it's ultimately relying on how I interpret it, react to it, it's up to me to find the reasons, the meanings behind. Those are just events, itself can be bright or dark, light or heavy, but it's me who lead it form there, towards the goals I'm been dreaming about. I have the control, I have a choice, just like another great quote says:

Pain is inevitable, but suffering is optional.

October 06, 2016

iPad Pro 9.7 + Smart Keyboard weights

Here are the specs:

  • iPad Pro 9.7 Wifi model: 437g
  • Smart Keyboard: 230g
  • Smart Cover: 110g
  • 3rd Party Cases: 100~300g

And for comparison, here are the laptop specs:

  • MacBook Air 11 inch: 1.08kg
  • MacBook Air 13 inch: 1.35kg
  • MacBook Pro with Retina 13-inch: 1.58kg
  • MacBook Pro with Retina 15-inch: 2.04kg

Cited from from Apple official website with latest model.

That means iPad Pro 9.7 + Smart Keyboard is 667g, about 62% of lightest MacBook Air 11 inch(1.08kg), 413g lighter.

I considered about Apple's Smart Keyboard as the first option, I also got the chance to try my friend's Smart Keyboard, but at that time I felt it's a bit heavy. Maybe because I was using a iPad mini so when upgraded to iPad Pro 9.7, the tablet itself already felt heavier. I've looked for some 3rd party cases but a lot of them weight more than the Smart Keyboard(more than 230g). There are some "light-weight" 100g-ish cases but all feel not attractive...

So I ended up going back to Smart Keyboard. If it's almost the same weight, a portable and comfortable keyboard could help me in various ways I couldn't imagine(and it did!), the overall weight of the combination is 437g + 230g = 667g, almost half of MacBook Air 13-inch.

Note that there's no official data from Apple about the Smart Keyboard, I found it on some blogs, and some says it's 225g some says 230g.

July 31, 2016 ipad

Always There, Like A Mountain

Some people strike me as mountains, always there when you look upon, no matter how the environment changes.


Some of them are my close friends. Whenever I visit their blogs I know there're new contents waiting for me. Or I login to the game I've been AFK for such a long time, they're there inviting me to the party.

Some of them are connected on Internet, they don't know me but I've been following them for years. Michael Hyatt's "This Is Your Life" podcast is the central place for my mental nutrition and self improvement, Miyagawa's for trending tech news and Japanese anime/books/culture, Sensus WoW Rogue whenever I want to catch up my World of Warcraft rogue skills, and Blizzard Entertainment for high quality games all these years.

I'm not here to promote any of those things, what I want to say is, it's not hard to start anything nowadays, and if you get lucky you may even grab some spotlights on the stage, but it's always hard to keep going, even for games!

In this fast paced noisy world, those "mountains" give me a sense of order, calm me down when everything is in chaos. It shows me a way where to find the spiritual connection and emotional support, just like same old friends. No matter if you're a blogger, a youtuber, a gamer, a writer or any content provider, as long as you keep the persistency and frequency, you create a reliability.

I don't want to be a sky - too unstable and unpredictable, suddenly shout out with rain and thunderstorm. I want to be a humble stone, that shares certain similarites to a mountain. Nothing lasts forever - sun, stars, diamonds, but I hope the next time you pick up the stone of me, it's still the same old stone, and gives you a sense of calm and safety.

July 27, 2016

Organize Your Apple Notes with Folders - Nesting and Ordering

In the last post I wrote about migrating from Evernote to Apple Notes, here I want to show you how to organize your notes with similar features of Evernote.

Here is a screenshot of my Apple Notes notebooks.

Apple Notes folders - ordering and nesting

Create Nesting Folders

In Evernote you can create a Stack Notebook, you can do it too with Apple Notes, but seems like it can only be done in Mac, not iPad/iPhone.

  1. Create a new folder(Cmd + Shift + N)
  2. Drag this folder to the parent folder

Apple Notes create nesting folders

Tip: Hit "Enter" key to rename the folder, it's easier than single click the folder and wait for one second.

Difference Between Evernote Notebooks Stack

In Evernote you can't move any notes into a Stack Notebook itself, it's like a pseudo folder. But in Apple Notes a parent(stack) notebook is just like normal notebooks that can hold any notes. You may find it handy.

Ordering Folders

By default folders are in alphabet order, you can not move around notebooks to change its order. A common practice here is to assign some index numbers to the notebooks, like a notebook with name "00 Important" shows higher than "10 ABC".

Note that the default folder "Notes" is fixed, you cannot rename it nor reorder it, it always sit under "All iCloud", so you can use it as the inbox of all your notes.

Inbox Zero?

Inbox Zero is a technique to keep the inbox empty -- or almost empty -- at all times, and in the context of notes taking, it means you set a "Inbox", all notes go to that folder first, then at the end of the day you move the notes to respective folders.

I've heard it long time ago, and I'm applying same technique to Google Inbox. But for notes taking it feels overwhelming, at least for me.

Right now I'm only putting certain notes -- blog ideas, inspirational quotes, receipts etc, that I know exactly where it belongs to, and have a good chance to review them later -- to folders, for others they just remain in the default "Notes" folder. I don't want to waste brain energy on each note thinking "hmm.. which folder should I put it", most of the time I can find it through search so that's enough for me.

I find myself with the nesting folders and good orders, I had no difficulties transfer from Evernote, and the overall experience with Apple Notes has been great.

July 09, 2016 evernote, Apple Notes

Migrate Evernote to Apple Notes 2016

Evernote recently changed their price plans, free account can only sync across 2 devices.

Evernote free account sync limitation

The change itself is okay, you can't blame the company trying to make some money and make better products for their core users, but after using it for 7 years, and all the "improvements" the company has made during the time, I realized it's not the right tool for me. I don't need presentation mode, nor chat, or any other collaboration/business features, I just want to take notes. I did upgrade to Pro user before but I found I was never using any of those features heh. This change of prices gives me a perfect chance to look for alternatives.

Apple Notes, on the other hand, is getting better and better. Some of the benefits are:

  • Free: No more Evernote "Upgrade" noise, nor limitation of sync devices. Yes it's limited to Apple devices, but if you're an Apple user then this is not a problem, plus you can access for the web version too.
  • Clean UI and minimum features: In its core it's just a simple notes taking app, with right enough features to make it powerful. You can create folders to organize your notes, and even nesting them. There is no tag system but I can always find my notes with search.
  • Better integration with Apple products: probably just a personal preference, but when I browse websites or reading on iPad, I really love the split view to open Apple Notes, lightening fast and easy to use, and after dropping the notes I can easily get back.

Import Notes from Evernote to Apple Notes

  1. Cmd + A to select the notes you want to export to Apple Notes, click "File -> Export Notes..." and save as a .enex file.
    Export from Evernote

  2. Open Apple Notes, click "File -> Import Notes..." and choose the previous .enex file
    Import to Apple Notes

  3. Notes will be imported into a folder called "Imported Notes"

Further reading

Organize Your Apple Notes with Folders - Nesting and Ordering

Fun reading

Recently I tweeted about another article about this change.

This isn’t really about Evernote in particular. It’s about how we all use services today without really owning anything. Downloading an app and paying a subscription fee doesn’t entitle you to much, ultimately. Evernote, like so many apps we love, is really just granting you a license to use its service when you sign up for an account.

It raises a reasonable concern. The web and tech industry is changing rapidly, 10 years later which service can still be there, and what happens when it hit and end, or an action-required kind of change, what options do we have then? What do we really own?

July 09, 2016 evernote, Apple Notes

Check Alert Message with Poltergeist or Capybara Webkit

Use accept_alert to get the alert message.

  • Poltergeist ignores alerts/confirms by default(source)
  • Poltergeist has had support for Capybaras modal api since September 2015( source)

That means you can same syntax for Poltergeist or capybara-webkit.

expect(accept_alert).to eq("Javascript alert message")

# or with block syntax

# will fail if alert message doesn't match
accept_alert("Javascript alert message") do 
  # next expectation

The first one expect(accept_alert).to reads a bit weird, but that's the return value of accept_alert.

June 28, 2016 capybara, Testing, poltergeist

CSS: Highly Customizable Text Underline

If you’re not happy with the default text-decoration: underline, want to tweak the thickness of the underline or vertical space between the text and the underline, then you may want to the background trick introduced in this post. Medium is also using this kind of technique.

// use background image to draw the underline
// this way we can tweak the vertical space between text and underline
a {
  text-decoration: none;

  background-image: linear-gradient(to bottom, rgba(0,0,0,0) 50%, rgba(0,0,0,.6) 50%);
  background-repeat: repeat-x;
  background-size: 2x 2x;
  background-position: 0 22px;

A quick demo of how it looks like:

text underline with background image demo

One caveat of this approach is, the position and thickness of the underline is depending on the font size. So if you’re using a different font-size as I do in the demo, you may need to change the background-position to fit your design.

Also if you want to apply it to different part of your page which all have different font-size, you will need to figure out the exact size for each part.

In my blog I’m using SCSS variables to document this behavior.

$post-font-size: 20px;
$underline-size: 2px;

background-size: $underline-size $underline-size;
background-position: 0 ($post-font-size + $underline-size);
June 06, 2016 css

Add binding.pry breakpoint dynamically with pry-byebug

When debugging if you want to check at some lines where you forget to put the binding.pry, you could use some help from pry-byebug's break points feature.

You can set and adjust breakpoints directly from a Pry session using the break command:

break SomeClass#run            # Break at the start of `SomeClass#run`.
break app/models/user.rb:15    # Break at line 15 in user.rb.

Please bear with me with this example as a showcase.

scenario "Guest can't view draft post" do
  post = create(:post, title: 'Vim', published_at: nil)
  visit post_path(post)
  expect(page).not_to have_content('Vim')

Suppose you put the first binding.pry there to check the creation of post, then somehow you also want to check what's going on in the controller, normally you would stop/finish the spec and drop the binding.pry to controller and rerun the spec. With pry-byebug you could set the breakpoint in the runtime: when the execution is stopped before the visit post_path(post)

[1] pry(#<RSpec::ExampleGroups::Posts>)> break PostsController#show

  Breakpoint 1: PostsController#show (Enabled)

  10: def show
  11: end

Now the breakpoint is set, if you continue the spec then it'll stop at the posts#show action.

This is also very useful when you check some codebase you're not familiar with like gems, during the debugging you also want to check some local variables inside a block or so, with the break command now you don't need to make changes to the library and restart your rails server.

June 06, 2016 Testing

Poltergeist Change Window Size

The default window size for poltergeist is 1024 x 768, in some cases you may want to change it to fit your specs.

Change Window Size Per Spec

page.driver.resize_window 1200, 768

Then you can check it this way.

page.driver.browser.client.window_size # => [1200, 768]

Note that this will not change the default window size for other specs, so no need to resize it back.

Change Window Size Globally

If you're using RSpec, you may want to create a metadata tag for it.

RSpec.configure do |config|
  config.before(:example, :mobile, type: :feature) do
    page.driver.add_headers("User-Agent" => "iPhone")
    page.driver.resize_window 320, 568

Here we registered a :mobile metadata tag to change the window size to 320, 568, also set the user agent to further simulate the request from a mobile.

scenario "Do something in mobile", :js, :mobile do
  page.driver.browser.client.window_size # => [320, 568]

Change Default Window Size

You could also customize the window size when register the poltergeist drive.

# spec/support/capybara.rb
require 'capybara/poltergeist'

Capybara.register_driver :poltergeist do |app|, window_size: [1600, 768])
Capybara.javascript_driver = :poltergeist
June 05, 2016 rspec, poltergeist

Ruby Include module with arguments

Ruby Module is an easy and great way to encapsulate related methods/constants and extend a class, but sometimes I find myself really want to tell it something about the current class.

A pseudo code of my "wish" looks like this: of course it's invalid, Ruby doesn’t allow us to do so.

class Post < ApplicationRecord
  include Publishable(column_name: :published_at)

Recently I read a blog post about how the author learned from reading some ruby gems' implementation to allow including a module with argument. Sounds fun so I gave it a try.

When you may want to include a module with arguments?

Let's first see an example, this may not be practical but at the moment I couldn't think of other great ones so please bear with me.

module Publishable
  def publish

class Post < ApplicationRecord
  include Publishable

There's nothing wrong with this code but some may argue that the Publishable module depends on the published_at column name, if someone renames the column to published_on then it'll be broken, it's coupled to the Post class.

One way to solve it may look like this:

module Publishable
  def publish
    update(publishable_column_name =>


  def publishable_column_name
    raise NotImplementedError

class Post < ApplicationRecord
  include Publishable


  def publishable_column_name

Now the Publishable is relying on its "host"(Post) to define the method publishable_column_name to explicitly tell it the column name, otherwise it will raise the not implemented error. But the downside is the module's requirement leaks to Post, and that's arguably break the purpose to use a module, which is to group all methods of a concept in one place.

I'm thinking this could be a use case for the technique I'm gonna show you in this blog post.

Trick: A Class Inherits From Module

How the trick work is already introduced in the article above, let's fast forward to the end result now.

class Publishable < Module
  def initialize(column_name)
    @column_name = column_name

  def included(base)
    column_name = @column_name

    base.class_eval do # self is Post class
      define_method(:publish) do  
        update(column_name => # self is Post object

class Post < ApplicationRecord

The notable things are

  • class Publishable < Module, we're not declaring a module, instead we're making a class that inherits from module
  • When we include this module, we can now initialize it with any arguments
  • The arguments will be available inside the Publishable "module", hence no the knowledge is decoupled
  • Use define_method(:publish) { } instead of def publish, latter will make you lose the context and you can't access column_name variable anymore

Why It Works?

I'm gonna borrow the code from the article, this is how Rubinius handles module and is identical to MRI Ruby:

def include?(mod)
  if !mod.kind_of?(Module) or mod.kind_of?(Class)
    raise TypeError, "wrong argument type #{mod.class} (expected Module)"
  # snip

When we do include SomeModule, this code will be executed to check if the target is a valid module. The trick is how we could manage to pass that check, that is "something is kind of Module and not kind of Class".

class Publishable < Module

Publishable.kind_of?(Module) # => true
Publishable.kind_of?(Class) # => true # => true # => false

With this trick you can pass whatever dependencies from the host to the module. Hope you find it useful, and let me know if you find a good use case with it in real world 😁Not sure if it's yet another case of abusing Ruby's flexibility to driver it too far, I do concern about its possible confusion when bring to teams in which people are most likely not aware of this kind of hack.

Further Reading

These 2 gems are using the same technique, and their full implementations are really easy to read and follow.

May 28, 2016 Ruby