Your friends at Viget present Extend, a Code & Technology Blog

Functional Programming in Ruby with Contracts

I read Thomas Reynolds’ My Weird Ruby a week or two ago, and I loved it. I’d never heard of the Contracts gem, but after reading the post and the well-written docs, I couldn’t wait to try it out. I’d been doing some functional programming as part of our ongoing programming challenge series, and saw an opportunity to use Contracts to rewrite my Ruby solution to the One-Time Pad problem. Check out my rewritten encrypt program:


Check your Props!

I recently attended the inaugural React Week workshop in Provo, Utah (organized by Tyler McGinnis and sponsored by DevMountain) to learn about React, React-Router, and Firebase from the delightful Ryan Florence. One of the interesting topics that Ryan touched on is React's prop validation, which he insisted is one of the most important features of the library. This isn't surprising since JavaScript lacks a strong type system, which can lead to some interesting and hard to track down bugs.

React's PropTypes let you enforce that the incoming props for a component match what it's expecting to receive, which can help mitigate issues like trying to call array methods on non-arrays or attempting to use a value that turns out to be null. React gives you some helpful methods for doing these checks but they only protect you if you declare PropTypes for all the props your component uses. What if you or another developer working with one of your components sets a prop that doesn't have a PropType? React's prop validation can't help you there.

So I whipped up a little mixin to warn developers who make this mistake.

View the Mixin (gist)


Organizing Nested Selectors in Sass

I love trying to figure out the best organizational systems for my code. At Viget, FEDs and Devs do regular code reviews and I usually take that opportunity to glean tips from colleagues on how to improve what I'm doing. Organizing CSS has been debated plenty, but what about preprocessed CSS? If you're using Sass/Scss or Less there's the additional challenge of organizing nested selectors. I've been thinking about this lately and here's where I've landed.


How to 3D Print Without a 3D Printer

If you have the Internet, you’re aware that 3D printing is a thing and that you can make some pretty cool things with a printer at your disposal. You probably know that a decent printer can run you anywhere from $600 to $4000+, which is a hefty price tag for something you might just want to try out. Luckily, you don’t need your own printer to make your own inventions, and this guide will show you how.


Better Scroll and Resize Event Handling

If you've written any non-trivial JavaScript targeted at the browser, then you've probably had to wire up a scroll or resize handler to the window in order to trigger some behavior in response to user scrolling or viewport size changes. Since you're a Good Programmer, you're also aware that these events tend to fire rapidly. As a result, if you attach a handler that is either computationally expensive or requires reading from or writing to the DOM, you're gonna have a bad time.

Enter: throttle and debounce functions.

Throttle results in rate-limited function invocations. A throttled function is executed no more than one time in a given interval regardless of how many times it is invoked.

Debounce results in deferred function invocation. A debounced function will not be executed until a configured delay after the last invocation. Alternatively, with an `immediate` flag, it can also be invoked at the first call.

A Visual Illustration of Throttle vs. Debounce

A Better Way

We use these utilities frequently in our apps and, while not all use cases require the same setup, many of my projects end up using a variation of the following pattern: 


// windowEvents.js

/*
 *  One caveat: many libraries will provide throttle,
 *  debounce, and event bindings for you. This example
 *  assumes nothing about your project's requirements.
 *  I recommend leveraging any existing libs you are
 *  using before pulling in something new.
 */

var events   = require('dom-events');      // npm module
var throttle = require('./util/throttle'); // local module
var debounce = require('./util/debounce'); // local module

// cache dom
var body = document.body;

// calculate viewport dimensions
var getDimensions = function() {
  var rect = body.getBoundingClientRect();

  return {
    height: rect.bottom - rect.top;
    width: rect.right - rect.left;
  }
}

// define scroll and resize handlers using throttle and debounce
var listeners = {
  scroll: {
    throttled: throttle(function() {
      events.emit(window, 'scroll.throttled', { scroll: body.scrollTop });
    }, 100),

    debounced: debounce(function() {
      events.emit(window, 'scroll.debounced', { scroll: body.scrollTop });
    }, 100)
  },

  resize: {
    throttled: throttle(function() {
      events.emit(window, 'resize.throttled', { dimensions: getDimensions() });
    }, 50),

    throttledLazy: throttle(function() {
      events.emit(window, 'resize.throttled.lazy', { dimensions: getDimensions() });
    }, 150),

    debounced: debounce(function() {
      events.emit(window, 'resize.debounced', { dimensions: getDimensions() });
    }, 100),

    debouncedLazy: debounce(function() {
      events.emit(window, 'resize.debounced.lazy', { dimensions: getDimensions() });
    }, 300)
  }
}

// attach a listener to `window.onscroll`
events.on(window, 'scroll', function(e) {
  Object.keys(listeners.scroll).forEach(function(key) {
    listeners.scroll[key]();
  });
});

// attach a listener to `window.onresize`
events.on(window, 'resize', function(e) {
  Object.keys(listeners.resize).forEach(function(key) {
    listeners.resize[key]();
  });
});

This is great. We declare which methods we want called for each of the events we're interested in: 'scroll' and 'resize.' Then, to each of those events we attach a single handler that invokes all of the throttled and debounced methods we set up. As seen above, the throttled and debounced methods simply re-emit namespaced events to which you can attach any number of handlers with reckless abandon!

// elsewhere in your project, attach handlers to
// the throttled and debounced events

events.on(window, 'resize.throttled', function(e) {
  // do some work that needs to happen at regular
  // intervals during continuous resize events

  console.log(e.dimensions);
  // => { height: 640, width: 900 }
}

events.on(window, 'scroll.debounced', function(e) {
  // do some computationally expensive
  // calculation after scroll

  console.log(e.scroll);
  // => 416
}

Snippet or Standalone Module?

Despite the utility of this technique, it is a poor candidate for becoming a standalone module since it's difficult to make broad assumptions about potential use cases, the source of the throttle and debounce functions, or what event system a project uses or even which listeners a project will require. However, this is a great snippet to stash in your JavaScript utility belt.

Going beyond...

Here are some additional ideas for how you might tweak this concept to fit your use case.

1. Make the function accept a configuration object that resembles the listeners var in the above snippet.

var listeners = { .. }; 
require('windowEvents')(listeners);

2. Allow a context other than 'window' to be used

// assume the above snippet is repurposed into a module
// called 'rescrollEvents' whose argument is the context
// in which to bind the scroll and resize events

require('rescrollEvents')(document.body);

3. Both of the previous ideas combined. Now this could potentially be reused widely without modification given the flexibility of its configuration.

var listeners = { .. };
require('rescrollEvents')(window, listeners);

What do you think? How have you solved this problem on your projects?