Speaker

Aji Slater

Aji Slater

Development Team Lead, thoughtbot

Chicago, Illinois, United States

Actions

I started my adult-like career years as a theatre professional, a vaudevillian to be specific. Toured with Ringling Brothers, juggled through Canada, and made corporate types laugh at conferences. But I spent more time making my website than performing. In 2015 I got serious about computers as a focus and went to Dev Bootcamp and learned Ruby, Rails, and js. I've been working as a professional developer ever since and haven't looked back. I might not be Banksy.

Area of Expertise

  • Information & Communications Technology

Topics

  • ruby
  • ruby on rails
  • Version control
  • pair programming
  • programming
  • react
  • APIs
  • TDD
  • TDD & BDD
  • Automation
  • Productivity

Zen and the Art of Incremental Automation

Automation doesn’t have to be all or nothing. Automating manual processes is a practice that one can employ via simple principles. Broad enough to be applied to a range of workflows, flexible enough to be tailored to an individual’s personal development routines; these principles are not in themselves complex, and can be performed regularly in the day to day of working in a codebase.
Learn how to cultivate habits and a culture of incremental automation so even if the goal is not a full self-service suite of automated tools, your team can begin a journey away from friction and manual tasks.

== The Details
This talk will describe principles the audience can employ to improve painful manual processes and introduce automation into their, and their teams', workflow. These principles are not in and of themselves complex, and can be performed regularly throughout the day to day tasks of working in an application's code and infrastructure. With even infrequent use, they will slowly layer in automation to reduce the friction of manual tasks for a project. The goal of these principles is to develop habits and a practice so that even if they never yield a full self-service automation suite, the practice will allow for valuable enhancements for nearly any project. The principles are broad enough so as to be applicable to a wide range of workflows and tailored to suit an individual's personal development practice.

- Document the manual processes
* Every manual action should generate an artifact or potentially improve an existing one as well as completing its task
* avoid the decision paralysis of deciding if something is worth documenting by documenting everything
* find low-friction paths to introducing new documentation

- Small improvements are large in aggregate
* Without the cognitive load or productivity cost of drastic changes or large amounts of work
* any small improvement is an improvement nonetheless

- Collaborate early and often
* if the goal is many small improvements making drastic change, many small improvements from many contributors decreases the time it takes to reach those heights.

== Outline
We'll explore the idea of incremental automation and the practice of automating by using practical examples and these steps. This will be the majority of the time of the talk, and we'll derive the principals from the examples by the end.

I. Document the manual process

* documentation is code, the person reading the documentation and performing the tasks is the CPU. You are the CPU.
* the documentation is the pseudocode that will eventually become the automation

II. Use the documentation to perform the task

* even if you wrote it, referring to and using the documentation will iteratively lead to it being more clear
* because "you two weeks from now" is essentially a different person from the you that wrote the doc, you'll be able to iterate on making the steps more clear
* edge cases and error handling will likely arise as you use the doc more than once

III. Make the documentation into a script

* I like the gem "runbook" by braintree, but it can be as simple as a bash script or a plain ruby file etc.
* each step in the doc should be a prompt on the screen, and require input from the developer doing the tasks to continue

IV. Check the script (the living version of the documentation) into version control

* this is now the source of truth for this process, if it was in a knowledge base system like confluence, link to the script
* at the start, the documentation and the script should look very similar, with a little bit of code syntax interspersed
* the sooner you collaborate, the sooner the rest of the team can contribute

V. Identify which step to automate first

* any number of heuristics can make this choice. easiest to automate? worst pain point? most error prone? you do you.
* If there is a step that is "copy paste this code into the terminal" that's a prime candidate for automating it, you already have the code written
* next time you run the script, you'll do one less step!

VI. Continue automating as time and need allows.

* never get the whole thing automated, but it's 50% there? that's 100% more automation than you had before! (someone check my math)

====
While it is widely applicable, the audience I hope to reach is that developer or team who is bogged down in manual processes. Often those manual processes seem un-automatable, or that the time can't be spared to go off to yourself, away from feature work, and craft a wholly behind-the-scenes script or automation. I intend to give them the tools, and the permission (become sometimes all you need is for someone to say something you're already thinking), to not have to deal with the all-or-nothing automation and build up that support over time, step by step.

== The Pitch
Practicing automation is valuable across a wide range of projects and applications. Some teams have huge processes that take a great deal of time and energy, and returns on investing in automation will be powerful, and some teams have small tasks that could also be automated. The small tasks might not lead to monumental results, but automation can still provide value in both arenas.

These practices and techniques were used by a product team I worked with to wrangle several of our manual tasks into manageable automated systems. We have "battle tested" these ideas and they added a lot of value, and even avoided burnout of some of our team. I'd like to impart some of what we learned, not just from 20,000 foot view, but from our experience actually implementing this approach. Our specific examples might not be applicable to every team or situation, but we have demonstrated some process or workflow for dealing with issues that arise putting this concept to work.

First Public Delivery: RubyConf Mini 2022 (Providence USA)

Your TDD Treasure Map

We know testing is vital and makes refactoring painless. But how to set sail to that TDD treasure? Yarr, we need to test to get experience, but need experience to test. Let’s draw a map with simple strategies for identifying test cases and building a robust test suite. X marks the spot w/ TDD tools for newbies and seasoned pirates alike.

== The Details
It’s easy to find the benefits of testing and test-driven development. There’s a reason why the ruby community is gaga over red to green, robust, well-rounded, and high code coverage test suites. This session assumes that the audience does not need convincing to want to test. The "sweet spot" audience is those who still have trouble deciding what to test before they write a line of application code.

They'll leave with a technique built on BDD that will allow them to make real, concrete decisions on what in their current work should/could have a test written. Going from business rules, product definition and requirements to pseudocode to tests is straightforward with this technique, and each step informs the next, bridging that gap between blank file and test suite.

Outline -

# TDD is good
* prevent regressions
* helps prevent complexity by setting small tasks & goals
* safer refactoring
* increasing returns with the lifetime of the project
* living documentation

# TDD is Hard
* how do we know what to test when we haven't written the code?

# Introduce the TDD Treasure Map technique
## The Map
* entry points
* where does this section of code begin?
* branches
* what questions exist that change the flow of the code?
* if statements, side effects, polymorphism etc
* end points
* where does this section of code under test end?
* what are the states that lead to there?
* translate entry points to test setup
* translate end points to expectations
* given, when, then

## Simplified example
* use real world language and situations to draw the map & tests
* simple example
- one ruby class or method, no dependencies
- identify this as a unit test
- draw the map and follow through with tests
* complex example
- one class or method that depends on another
- draw the map and highlight where dependencies come into play
- talk about how a mock or stub would play into keeping the tests simple
* zoom out
- show how this technique can apply at all the layers of the testing pyramid
- use example of user-flow to demonstrate at a product-size level

== The Pitch
The talk centers around a technique I’ve refined while mentoring new programmers. They’ve just learned how to write code, and now all of a sudden it sounds like they’re being asked to visualize all the code they’ll have in the future and devise tests for it before they start.

It involves drawing something like a map, hence the piratical theme, of the controller, the feature, the class, or the method you’re testing. Visualize (or draw out, or pseudocode!) this map from all the starting points you can think of, to all the end points you can think of.

Likely you’ve stumbled across a few things you hadn’t thought of before, and made the future code better in the process, hey this imaginary future feature doesn’t seem so far away! But wait.. still have to write tests first. How else do you know when you’re successful?

Taking the flowchart again, look at every endpoint. Every different way the code can resolve. Trace it back to the starting point, through however many decisions and turns it took to get there. What did you start with to reach that endpoint? That’s the start of your test. That’s your “given”. That path you traced is your “when”. That endpoint? You guessed it, the “then.”

Not only have you built a mental model of the feature you’re setting out to build, but you’ve devised your test cases. Now go write them! All of a sudden you have a map, you’ve got that friendly guide along feature development that is your test suite.

I’ve hashed over this talk idea with co-workers and colleagues, and many have taken it to heart and started using it in their work. Whether they’re beginners or experienced programmers, this is a tool I’ve found can work in many different situations, and help get those first high-level feature tests up and running.

I’ve been in tech for a handful of years now, but I’ve been a speaker for over a decade. I’ve taken the stage at corporate conferences and trade shows, as well as theatres and circus rings. I try to bring a lightness and excitement to my talks to share the excitement I feel about the topics I cover.

First Public Delivery: RailsConf 2022 (Portland USA)
Preferred Session Length: 30 Minutes

Hotwiring My React Brain

Hi. Have you been writing Rails API-mode json backends for React front ends for the last few years? Me too.

Have you been daydreaming about the days when you could just write a view template and render some html server-side? Me too.

Have you been wondering if it's possible to have rich, snappy UIs with only Rails, and very little js? Me too.

Are you now working on a fully Hotwire and Turbo app, having to re-learn everything you've grown comfortable with in front-end development? Me.. huh? no?

Well come along and I'll show you how I re-implemented my conception of the client side with Rails' Hotwire view layer.

The Unbreakable Code Whose Breaking Won WWII

== Briefly
After the last carrier pigeon but before digital encryption algorithms, there was the Enigma machine. An ingenious piece of pre-atomic age technology encoded German military secrets during World War II, baffling code-breakers with mere physical rotors, and switches, without elliptic curves or private keys.

Delve into object-oriented programming and bring the Enigma machine back to life with an emulator built in Ruby. Unravel the secrets of this nigh-unbreakable cipher device, witness OO principles unlock its mysteries, discover the power and versatility of the patterns we use as developers and how they mirror the Enigma's inner workings.

== The Details
“Object Oriented Programming’s touted strength lies in its ability to model the real world”. That’s all well and good, but finding practical examples where all the moving parts relate to objects “in the real world” can be tricky.

Enter the object that is the Enigma device. Famous because of its involvement in World War II, it was invented in the 1910s, requiring real moving parts and physical mechanisms working together in a system to produce its outcome. Looking at pictures of the actual historical devices can help gather requirements without abstraction or indirection.

It exists as a physical object that performs an operation (encryption) that would be typically handled completely digitally today therefore Enigma has a unique connection between physical and digital processes, making it easier to understand and manage.

First:

I’ll introduce the story of the device, its beginnings as a commercial product through adoption by the German military and its involvement in WWII. Finally, the team of code-breakers at Bletchley Park where the Allies eventually built a system for decrypting the messages.

Although the history section will be comparatively short, I will nevertheless highlight the role of women code-breakers whose efforts at Bletchley are so often passed over. Their involvement was instrumental in the group’s success, and the story of Enigma’s downfall would never have been written without them.

Secondly:

I’ll demonstrate how Enigma works. The machine is fairly uncomplicated, and there is no prerequisite knowledge required to be able to understand its operation and inner workings after a brief primer. Extensive illustration will provide enough visual context and support for the audience to be able to imagine how the physical mechanisms operate.

Enigma consisted of a “keyboard” whose keys, when pressed, would send a signal through the inner workings and light up a small bulb indicating the letter resulting from encryption. Between the key and the light, it sent the signal through a series of rotors, each changing the input character to another. The rotors would advance on each key press, changing the path the signal took through the device and, therefore, the output character. It’s these simple components that we’ll be replicating in code.

Third:

Recreate the machine in code! We’ll build out the components of an Enigma machine (depending on time in the session, hopefully demonstrating the test suite as well) to convey examples of OO priciples and practices such as--

* single responsibility

* encapsulation

* dependency management and coupling

* inheritance

* interfaces and duck typing

A la the bicycle in POODR (Practical Object Oriented Design in Ruby), this simple machine will allow us a framework from which to explore how objects and their messages can be composed in an extensible and maintainable way through the application of OO design philosophies.

== Intended Audience
Someone still new to the concepts behind OO Programming. They may have heard some of the terminology, or perhaps some of the axioms involved...but haven't yet assimilated the WHYs and HOWs into their understanding. As Sandi Metz says in POODR, "This books assumes that you have at least tried to write object-oriented software. It is not necessary that you feel you succeeded, just that you made the attempt.

There might be some folks who are familiar with OO principles and design concepts that could use a refresher or another approach to understanding.

Those interested in the history of computing and how past events could inform or relate to what we do today.

== Outcomes
* better understanding of OO principles
* see the concepts at work
* for those more experienced:
* a refresher on the fundamentals
* a new perspective on known concepts
* fun takeaways
* If they didn't know about Bletchley Park, they will have enough of an introduction to look into it more
* a new idea for a early-into-a-new-language project.
* a shoutout to the women of Bletchley Park that did so much of the work and get none of the credit. Also an opportunity to celebrate the queer man at the epicenter of early computing theory.

== The Pitch
The subject has a unique connection between kinesthetically understandible physical operation of the mechanism (easy to grasp) and a digital data transformation process (more abstract, but common to our work as developers)

It allows for a less contrived metaphor for demonstrating OOP that comes from a complete system whose entirety can be kept in the mind at once.

It's an interesting and compelling story, spycraft and danger. It's more exciting to explore.

I’ve been in tech for a handful of years now, but I’ve been a speaker and communicator for well over a decade. I’ve taken the stage at corporate conferences and trade shows, as well as theatres and circus rings. I try to bring a lightness and excitement to my talks to share the excitement I feel about the topics I cover.

First Public Delivery: RubyConf 2023 (San Diego, USA)

This is not a pipe: replicating a functional pattern in an OO way

== Briefly
Rene Magritte, Belgian surrealist, painted a picture of a common brown tobacco pipe and underneath wrote the words, "this is not a pipe" (in french: ceci n'est pas une pipe). The Treachery of Images is one of his most famous works and this representation of double meaning and imitation is how it can feel implementing a functional programming concept in a language like Ruby.

There is no `|>` operator here, where everything's an object and sending messages is the order of the day. How can we leverage this pattern in an object oriented way? And why might we want to?

After all, in Ruby, "ceci n'est pas une pipe".

== The Details
So often do I find myself wishing that there was a mechanism built in to Ruby that would make a series of discrete operations straightforward and easily parsed by my teammates. But I've found that because it isn't a first-class language feature of Ruby, many folks I've worked with are either not aware of its "enshrinement" as a pattern or have interacted with it quite infrequently.

The concept is not an uncommon one to programmers, our frequently used shells have a pipe operator, and even a brief daliance with UNIX sorcery will likely have yielded some familiarity with it. Functional languages often have the concept of pipes built in with an operator `|>` or the like. Method chaining and method(calls(that(nest(themselves)))) are hardly unfamiliar territory.

It's not difficult to see why this is a common concept, transformation of data is fundamental to what computer programs do, and functional pipelines offer a robust framework for understanding complex operations.

I intend this session to introduce more Ruby developers to the pipeline pattern, even if it is not a first-class citizen of the Ruby ecosystem. The concepts explained here will start from basic OO principles and presuppose no more knowledge than Ruby fundamentals. The examples should be enlightening to those who have not worked with this pattern before, and offer a focused dive into the concept for those who are familiar but want to see how it can be useful to them in their work.

The session will explain the pattern and demonstrate how to build a pipeline in Ruby using TDD. This will add the benefit of showing those who might struggle with TDD a practical example of the workflow.

I'll frame the discussion with an introduction to the artwork "The Treachery of Images" by Rene Magritte, the surrealist painter.

[Wikipedia entry for The Treachery of Images][1]

The artwork's representation of a physical object as image, and it's bold yet unarguable statement "this is NOT a pipe" offers a way to talk about how we can build the pipeline pattern in a concise, easily understandable and developer-happiness focused way, even without a specific operator built into the language.

If we have time, we'll take a brief trip into the pipe operator that briefly became a part of Ruby, talk about why it was introduced, and eventually removed.

I. Introduction to pipelines
* what are their properties
- it's all about composition, function composition
- the source stage, the beginning
- the sink, or consumer, the last stage
* how they're used in functional languages
- F#, Elm, Elixir's pipe operator
- with first order functions, like javascript
* why and when might they be helpful
- what kinds of problems are they good for solving
- data transformation
- game loops
- testing is A DREAM when done right
- when might that complexity be too much
* when might you have implemented them without knowing it?
- map, reduce, etc. lend themselves to this idea
- method chaining can sometimes be something of a pipeline

II. Two types?
1. where one fn output is another's input
* like using `|` on the command line
* order is important
- the step before's output will have an effect on what the next step does
- types must match one to the next
2. where one data structure is acted on but passed to all steps
* "passthrough" pipeline
- the mental model of "dropping" the payload through a series of actors
* steps might "decide" to act or not based on the information in the payload
* order is important
- a step might act or not depending on previous steps
- the payload type will be the same, types aren't the limiting factor

III. Straightforward implementation
* something like reduce and lambdas
* that doesn't feel like "the ruby way"

IV. More OO, "ruby-like" implementation
* how is it different than simply the |> operator
* Pipeline class that marshals the operation
* Step class with shared inherited behavior

V. Escape hatch
* stop moving forward if something errors, cancel all future steps
* return that error to the caller of the pipeline
* implement this feature in our OO pipeline

VI. Dynamic pipelines
* not only deciding should each step act or not, but what steps should
be a part of the pipeline?
* implement in our OO pipeline

[1]: https://en.wikipedia.org/wiki/The_Treachery_of_Images

== The Pitch
"waitaminute... did I just write another functional pipeline?"

This is common refrain for me (usually in my head) while working. The pipeline pattern (like graph theory) is an elegant solution to so many situations in our work, and yet the pattern and concept hasn't filtered into our community, out of the functional world enough.

Because it's so familiar to me, and as someone who pairs often at work, I have experienced both introducing teammates to the pipeline pattern, and the excitement that comes along with getting to wield such a useful tool. I've been able to come up with a concise mental model for describing the pattern and its usefulness, and I would like to share it with a wider audience of Rubyists.

I’ve been in tech for the better part of a decade, but I’ve been a speaker, mentor and communicator for almost 20 years. I’ve taken the stage at corporate conferences and trade shows, as well as theatres and circus rings.

I bring a lightness and exuberance to my talks in order to share the excitement I feel about the topics I cover. I'm an accomplished conference speaker, with consistently polished visuals supporting funny and informative presentations.

Aji Slater

Development Team Lead, thoughtbot

Chicago, Illinois, United States

Actions

Please note that Sessionize is not responsible for the accuracy or validity of the data provided by speakers. If you suspect this profile to be fake or spam, please let us know.

Jump to top