# This document has moved! Itclass="_tkStr_1klyn_166">'s now [here](https:class="_tkCom_1klyn_170">//www.destroyallsoftware.com/compendium/types/baf6b67369843fa2), in The Programmer's Compendium. The content is the same as before, but being part of the compendium means that it's actively maintained.
garybernhardt's hand
The top 100 gists by star count
A♦
A♦
K♣
# Things that programmers don't know but should (A book that I might eventually write!) Gary Bernhardt I imagine each of these chapters being about class="_tkNum_1klyn_175">2,class="_tkNum_1klyn_175">000 words, making the whole book about the size of a small novel. For comparison, articles in large papers like the New York Times average about class="_tkNum_1klyn_175">1,class="_tkNum_1klyn_175">200 words. Each topic gets whatever level of detail I can fit into that space. For simple topics, that's a lot of space: I can probably walk through a very basic, but working, implementation of the IP protocol. More subtle topics will get less detail: for RSA, maybe I'd (class="_tkNum_1klyn_175">1) give a rough sketch of the number theory, (class="_tkNum_1klyn_175">2) show that we can treat arbitrarily large byte arrays as numbers, and (class="_tkNum_1klyn_175">3) say class="_tkStr_1klyn_166">"combine them in the obvious way".
K♣
Q♥
(Chapters marked with * are already written. This gets reorganized constantly and class="_tkNum_1klyn_175">10 or so written chapters that Iclass="_tkStr_1klyn_166">'m on the fence about aren't listed.) Programmer Epistemology class=class="_tkStr_1klyn_166">"_tkCom_1klyn_170"> * Dispersed Cost vs. Reduced Cost class=class="_tkStr_1klyn_166">"_tkCom_1klyn_170"> * Verificationist Fallacy class=class="_tkStr_1klyn_166">"_tkCom_1klyn_170"> * Mistake Metastasis The Overton Window Epicycles All The Way Down The Hyperspace Gates Were Just There Software Design class=class="_tkStr_1klyn_166">"_tkCom_1klyn_170"> * Structured Design: Understanding Graphs
Q♥
J♠
A queue that you can pass to IO.select.
# A queue that you can pass to IO.select. # # NOT THREAD SAFE: Only one thread should write; only one thread should read. # # Purpose: # Allow easy integration of data-producing threads into event loops. The # queue will be readable from select's perspective as long as there are # objects in the queue. # # Implementation: # The queue maintains a pipe. The pipe contains a number of bytes equal to # the queue size.
J♠
10♦
# Has your OS/FS/disk lost your data? # cd to the directory containing your project repositories and run the command # below. (It's long; make sure you get it all.) It finds all of your git repos # and runs paranoid fscks in them to check their integrity. (set -e && find . -type d -and -iname class="_tkStr_1klyn_166">'.git' | while read p; do (cd class="_tkStr_1klyn_166">"$(dirname "$pclass="_tkStr_1klyn_166">")" && (set -x && git fsck --full --strict)); done) && echo class="_tkStr_1klyn_166">"OK" # I have class="_tkNum_1klyn_175">81 git repos in my ~/proj directory and had no errors. # You might get messages about dangling commits, dangling blobs, etc. Those # aren't errors. If it prints class="_tkStr_1klyn_166">"OK" at the end, your repos are all valid.
10♦
9♣
This tool is used to compare microbenchmarks across two versions of code. It's paranoid about nulling out timing error, so the numbers should be meaningful. It runs the benchmarks many times, scaling the iterations up if the benchmark is extremely short, and it nulls out its own timing overhead while doing so. It reports results graphically with a text interface in the terminal. You first run it with --record, which generates a JSON dotfile with runtimes for each of your benchmarks. Then you change the code and run again with --compare, which re-runs and generates comparison plots between your recorded and current times. In the example output, I did a --record on the master branch, then switched to my scoring_redesign and did a --compare. In my output, three of the benchmarks' runtimes look to be unchanged; the other three got
9♣
8♥
#!/usr/bin/env ruby require class="_tkStr_1klyn_166">'base64' require class="_tkStr_1klyn_166">'nokogiri' require class="_tkStr_1klyn_166">'uri' def main html = Nokogiri::HTML($stdin.read) inline_all_images(html) inline_all_css(html) $stdout.write(html.to_s) end
8♥
7♠
require class="_tkStr_1klyn_166">"erb" require class="_tkStr_1klyn_166">"pathname" DOT_TEMPLATE=<<-END digraph { size=class="_tkStr_1klyn_166">"class="_tkNum_1klyn_175">20,class="_tkNum_1klyn_175">20"; overlap=false; sep=class="_tkNum_1klyn_175">0.4; graph [fontname=Helvetica,fontsize=class="_tkNum_1klyn_175">10]; node [fontname=Helvetica,fontsize=class="_tkNum_1klyn_175">10]; edge [fontname=Helvetica,fontsize=class="_tkNum_1klyn_175">10]; rankdir=TB;
7♠
6♦
#!/usr/bin/env bash set -e if [ -e static ]; then rm -r static fi mkdir -p static sass src/sass/main.scss > static/application.css $(npm bin)/browserify src/js/main.js > static/application.js cp -r src/html/* static
6♦
5♣
# Goal: put a non-Rails-aware Ruby library using normal class="_tkStr_1klyn_166">`require`s in # lib/sim. Have it transparently reloaded between requests like Rails app # code is. # # The code here goes inside of your configure block in # config/environments/development.rb. There are two parts, commented inline. # Reload code whenever the simulator changes. config.watchable_dirs[class="_tkStr_1klyn_166">"lib/sim"] = [:rb] config.watchable_files << class="_tkStr_1klyn_166">"lib/sim.rb" # Manually unload and reload the simulator before every request. This assumes
5♣
4♥
Turning The Design Clock Back Object-oriented design principles haven't had the effect we hoped for. The SOLID principles are excellent design guidelines, but experience shows that programmers find them difficult to follow. What do we do about this? Surprisingly, the Structured Design literature of forty years ago contains compelling solutions to many current design problems. They're simple and easy to understand, but were lost in the noise as OO rose to popularity. We'll reinterpret these simple design ideas in a modern context, finding that many of our most promising new design ideas resemble them. Rapid web application development, the area of professional programming in most dire need of design improvements, will serve as an example.
4♥
3♠
# I don't really see any services here. What I see is: # - Normal HTTP boundary stuff (params flash, redirect). # - Model creation and retrieval. # - Warden manipulation, which is an odd done but smells like boundary. # # I left all of the HTTP boundary stuff in the controller (and only the # controller). I moved the model creation/retrieval into simple class methods # in the models. I moved the warden manipulation stuff into # ApplicationController (with caveats that I'll discuss inline). # # Commentary on each class follows:
3♠
A♦
find $(manpath | tr class="_tkStr_1klyn_166">':' class="_tkStr_1klyn_166">'\n') -iname class="_tkStr_1klyn_166">'*.class="_tkNum_1klyn_175">1' | xargs cat | (LC_CTYPE=C tr -C class="_tkStr_1klyn_166">'[:alnum:]-_' class="_tkStr_1klyn_166">'\n') | egrep class="_tkStr_1klyn_166">'^--[\-_[:alnum:]]+$' | sort | uniq -c | sort -n
A♦
K♣
Probably a really bad implementation of word wrapping
class Wrap def self.wrap(s, max_length) raise ArgumentError.new(class="_tkStr_1klyn_166">"Maximum wrap length can't be class="_tkNum_1klyn_175">0") if max_length == class="_tkNum_1klyn_175">0 return [class="_tkStr_1klyn_166">""] if s.rstrip.empty? # Split into words and whitespace blocks blocks = s.split /(\s+|\S+)\b/ lines = [] line = class="_tkStr_1klyn_166">"" until blocks.empty?
K♣
Q♥
An excerpt from GCC's reload.c
static int find_reusable_reload (rtx *p_in, rtx out, enum reg_class rclass, enum reload_type type, int opnum, int dont_share) { rtx in = *p_in; int i; /* We can't merge two reloads if the output of either one is earlyclobbered. */ if (earlyclobber_operand_p (out)) return n_reloads;
Q♥
J♠
diff --git a/app/views/devise/shared/_links.erb b/app/views/devise/shared/_links.erb dissimilarity index class="_tkNum_1klyn_175">99% index 414904b..0b0b21d class="_tkNum_1klyn_175">100644 --- a/app/views/devise/shared/_links.erb +++ b/app/views/devise/shared/_links.erb @@ -class="_tkNum_1klyn_175">1,class="_tkNum_1klyn_175">19 +class="_tkNum_1klyn_175">1,class="_tkNum_1klyn_175">15 @@ -<%- if controller_name != class="_tkStr_1klyn_166">'sessions' %> - <%= link_to class="_tkStr_1klyn_166">"Sign in", new_session_path(resource_name) %><br /> -<% end -%> - -<%- if devise_mapping.registerable? && controller_name != class="_tkStr_1klyn_166">'registrations' %> - <%= link_to class="_tkStr_1klyn_166">"Sign up", new_registration_path(resource_name) %><br />
J♠
10♦
find ~/Downloads/Gmail -type f | grep -v class="_tkStr_1klyn_166">'\.git' | ruby -rdate -e class="_tkStr_1klyn_166">'today = Date.today; STDIN.each { |path| content = File.read(path.strip); begin; from = content.grep(/^From:/).fetch(class="_tkNum_1klyn_175">0); date = content.grep(/^Date:/).fetch(class="_tkNum_1klyn_175">0); puts from if Date.parse(date) > today - class="_tkNum_1klyn_175">365; rescue IndexError; end }' | while read line; do echo class="_tkStr_1klyn_166">"$line" | ~/.mutt/add-aliases.sh; done
10♦
9♣
#!/usr/bin/env bash main() { if [ ! -p .test-commands ]; then mkfifo .test-commands fi while true; do cmd=$(cat .test-commands) if [[ $cmd == class="_tkStr_1klyn_166">"" ]]; then continue else
9♣
8♥
set conf_name to text returned of ¬ (display dialog ¬ class="_tkStr_1klyn_166">"Enter conference name:" with title ¬ class="_tkStr_1klyn_166">"Schedule Conference" default answer ¬ class="_tkStr_1klyn_166">"" default button class="_tkNum_1klyn_175">2) tell application class="_tkStr_1klyn_166">"OmniFocus" tell default document set newProject to make new project with properties {name:conf_name} tell project conf_name make new task with properties {name:class="_tkStr_1klyn_166">"Schedule " & conf_name & class="_tkStr_1klyn_166">" in calendar"}
8♥
7♠
(set -e && ls content/*.markdown | while read p; do DATE=$(echo $p | cut -d class="_tkStr_1klyn_166">'/' -f class="_tkNum_1klyn_175">2 | cut -d class="_tkStr_1klyn_166">'-' -f class="_tkNum_1klyn_175">1-class="_tkNum_1klyn_175">3); TARGET=$(echo $p | sed class="_tkStr_1klyn_166">'s/-/\class="_tkCom_1klyn_170">//' | sed class="_tkStr_1klyn_166">'s/-/\//' | sed -E class="_tkStr_1klyn_166">'s/[class="_tkNum_1klyn_175">0-class="_tkNum_1klyn_175">9]+-//' | perl -pe class="_tkStr_1klyn_166">'s/^(.*\/.*\/.*\/)(.)(.*)$/\class="_tkNum_1klyn_175">1\u\class="_tkNum_1klyn_175">2\class="_tkNum_1klyn_175">3/' | sed -E class="_tkStr_1klyn_166">'s/-|_/ /g'); echo $TARGET; mkdir -p $(dirname $TARGET); echo class="_tkStr_1klyn_166">"<\!-- $DATE -->" > $TARGET; cat $p >> $TARGET; rm $p; done)
7♠
6♦
using the git reflog
# I have a repo with two commits failbowl:temp(master) grb$ git shortlog Gary Bernhardt (class="_tkNum_1klyn_175">2): commit class="_tkNum_1klyn_175">1 commit class="_tkNum_1klyn_175">2 # I destroy the second commit failbowl:temp(master) grb$ git reset --hard HEAD^ HEAD is now at 7454aa7 commit class="_tkNum_1klyn_175">1 # It's gone
6♦
5♣
x = function() y = function() local table = class="_tkNum_1klyn_175">5 end local old_table = table y() assert(table == old_table and table ~= class="_tkNum_1klyn_175">5) end x()
5♣
4♥
#!/bin/bash set -e if [ $# -gt class="_tkNum_1klyn_175">0 ]; then # we have args filename=$class="_tkNum_1klyn_175">1 (set +e; grep -r class="_tkStr_1klyn_166">'spec_helper' $filename) > /dev/null if [ $? -eq class="_tkNum_1klyn_175">1 ]; then # no match; we have a stand-alone spec standalone_spec=class="_tkNum_1klyn_175">1 fi else # we have no args filename=class="_tkStr_1klyn_166">'spec'
4♥
3♠
It's a subscription-based screencast site, where I post a new five- to ten-minute screencast every week. For this, people pay a nominal fee around $class="_tkNum_1klyn_175">3 per month, giving them access to the full archives and new screencasts as they happen. The style would be similar to the screencasts I've posted on my blog: just me and the computer, recorded in one take, although with much practicing. I'd focus not on new languages and tools, but on the minute-to-minute mechanics of effective programming practices, with an obvious bias toward the stack and practices that I use.
3♠
2♦
Date: Thu, class="_tkNum_1klyn_175">3 Oct class="_tkNum_1klyn_175">2013 class="_tkNum_1klyn_175">17:class="_tkNum_1klyn_175">16:class="_tkNum_1klyn_175">51 -class="_tkNum_1klyn_175">0700 From: Gary Bernhardt <gary.bernhardt@gmail.com> To: info@wdsearch.com Subject: Mailing practices I suspect that you guys know this, but just in case: your emailing practices have been resulting in... less than good impressions among the people you aim to recruit. Here are some tweets, none of which were written by me: Ugh, Nicholas Meyler. Scummiest Scumbag Recruiter ever. - https:class=class="_tkStr_1klyn_166">"_tkCom_1klyn_170">//twitter.com/ryanbigg/status/class="_tkNum_1klyn_175">385918215559184384
2♦
A♦
inbox_blobs() { git ls-tree -r master | grep class="_tkStr_1klyn_166">'INBOX' | awk class="_tkStr_1klyn_166">'{print $class="_tkNum_1klyn_175">3}' | sort } diff <(cd ../Gmail && inbox_blobs) <(inbox_blobs) | grep class="_tkStr_1klyn_166">'<\|>' | while read marker hash; do echo class="_tkStr_1klyn_166">"$marker $(git show $hash | grep -m class="_tkNum_1klyn_175">1 '^Subject:')" done | sort
A♦
K♣
bench class="_tkStr_1klyn_166">"paths", :without_gc => true, :gc_time => true do PATHS[class="_tkNum_1klyn_175">0, class="_tkNum_1klyn_175">1000].each { |choice| Score.score(choice, class="_tkStr_1klyn_166">"x" * class="_tkNum_1klyn_175">16) } end Output: ...!.!.!.!.............................................. filtering paths Before: | --X----------------------- | After: | ---------X-------------------------| class="_tkNum_1klyn_175">0 class="_tkNum_1klyn_175">14.1
K♣
Q♥
failbowl:selecta(scoring_redesign) $ ruby ../readygo/readygo.rb --compare benchmark.rb .!.!.!.!.!.!.!.!..!.!.!.!.!.!.!.!.!.!...!.!.!.!.!.!.!.!............................................................................................................. filtering non-matching Baseline: | X-----------| Current: | X--------- | class="_tkNum_1klyn_175">0 class="_tkNum_1klyn_175">6.848 ms filtering matching exactly Baseline: | X-------------------| Current: | X | class="_tkNum_1klyn_175">0 class="_tkNum_1klyn_175">68.219 ms
Q♥
J♠
module RenderToHTML def self.book [title, css, body].join(class="_tkStr_1klyn_166">"\n") end private def self.title commit_hash = class="_tkStr_1klyn_166">`git log -class="_tkNum_1klyn_175">1 --pretty="format:%H"` %{ <div class=class="_tkStr_1klyn_166">"title"> <h1>#{TITLE}</h1>
J♠
10♦
open Parser;; open Stringutil;; type t = String of string | List of t list let rec of_module m = List (String class="_tkStr_1klyn_166">"module" :: of_definitions m) and of_definitions ds = List.map of_definition ds and of_definition (FuncDef func_def) =
10♦
9♣
# This is a stripped-down example based on Selecta's TTY handling. We store the # TTY state in class="_tkStr_1klyn_166">`tty_state`, then go into an infinite loop. When the loop is # terminated by a ^C, we try to restore the TTY state. It's important that this # work, but it doesnclass="_tkStr_1klyn_166">'t in some subtle situations, and I don't know why. # # Save this file as test.rb and run it via this command, where class="_tkStr_1klyn_166">`stty` should # successfully restore the TTY state: # bash -c class="_tkStr_1klyn_166">'echo | ruby test.rb' # # Next, run it via this command, where class="_tkStr_1klyn_166">`stty` should fail to restore the TTY # state: # bash -c class="_tkStr_1klyn_166">'echo $(echo | ruby test.rb)'
9♣
8♥
module TwitterLib def self.authenticate libs = [Twitter, TweetStream] libs.each do |lib| lib.configure do |config| config.consumer_key = ENV.fetch(class="_tkStr_1klyn_166">"TWITTER_CONSUMER_KEY") config.consumer_secret = ENV.fetch(class="_tkStr_1klyn_166">"TWITTER_CONSUMER_SECRET") config.oauth_token = ENV.fetch(class="_tkStr_1klyn_166">"TWITTER_OAUTH_TOKEN") config.oauth_token_secret = ENV.fetch(class="_tkStr_1klyn_166">"TWITTER_OAUTH_SECRET") end end end
8♥
7♠
#!/usr/bin/env ruby # This script tests par2 recovery when the par2 files themselves are corrupted. # Process: # class="_tkNum_1klyn_175">1. Generate a file containing all class="_tkNum_1klyn_175">256 possible bytes. # (More would be better, but it gets slow fast.) # class="_tkNum_1klyn_175">2. Generate par2 data for the file. # class="_tkNum_1klyn_175">3. Individually corrupt each par2 file at each offset. # (Write byte class="_tkNum_1klyn_175">0 unless the offset already contains byte class="_tkNum_1klyn_175">0; then, write byte class="_tkNum_1klyn_175">255.) # (Writing each possible byte would be better, but it gets slow fast.) # class="_tkNum_1klyn_175">4. After each corruption, verify the par2 data, then reverse the corruption. # class="_tkNum_1klyn_175">5. Produce a summary of what the par2 verification commands' output, along with the frequencies of each output string.
7♠
6♦
Automatically fix rubocop errors, with one commit per error
rubocop | egrep class="_tkStr_1klyn_166">' (W|C): ' | cut -d class="_tkStr_1klyn_166">' ' -f class="_tkNum_1klyn_175">3 | sort -u | sed class="_tkStr_1klyn_166">'s/:$class="_tkCom_1klyn_170">//' | while read cop; do git checkout . rubocop -a --only class="_tkStr_1klyn_166">"$cop"; if [[ $(git diff --stat) != class="_tkStr_1klyn_166">'' ]]; then git add --all git commit -m class="_tkStr_1klyn_166">"fix rubocop cop $cop" fi done
6♦
5♣
" Remap the tab key to do snippets, autocompletion or indentation depending on " the context (cobbled together by Gary Bernhardt; partly based on " http://www.vim.org/tips/tip.php?tip_id=class="_tkNum_1klyn_175">102) " " Because this uses the private class="_tkStr_1klyn_166">'Jumper' function in snippetsEmu, you'll need " to edit class="_tkStr_1klyn_166">'/.vim/plugin/snippetsEmu.vim' to make it public. To do that, just " replace all occurrences of class="_tkStr_1klyn_166">'<SID>Jumper' with just class="_tkStr_1klyn_166">'Jumper'. There were only " two occurrences in my copy. " " The g:snippetsEmu_key variable must be defined, but not to a function key. class="_tkStr_1klyn_166">" (I have no idea why function keys break it.) " I recommend something on the " leader prefix that you don't use.
5♣
4♥
class BowlingScorer: def __init__(self, rolls): rolls = rolls[:] self.score = sum(self.score_frame(rolls) for _ in range(class="_tkNum_1klyn_175">10)) def score_frame(self, rolls_left): roll1 = rolls_left.pop(class="_tkNum_1klyn_175">0) if roll1 == class="_tkNum_1klyn_175">10: return class="_tkNum_1klyn_175">10 + rolls_left[class="_tkNum_1klyn_175">0] + rolls_left[class="_tkNum_1klyn_175">1] roll2 = rolls_left.pop(class="_tkNum_1klyn_175">0) if roll1 + roll2 == class="_tkNum_1klyn_175">10:
4♥
3♠
def santa(people): return dict(zip(people, reversed(people))) def describe_santa(): bob, george, judy = class="_tkStr_1klyn_166">'bob jones', class="_tkStr_1klyn_166">'george jetson', class="_tkStr_1klyn_166">'judy smith' def takes_lists_of_people(): santa([bob, george]) def pairs_people_with_eachother(): pairs = santa([bob, george])
3♠
2♦
# Loop through git revisions, counting lines of Python # code, unit test code, cucumber code, and media. The # paths and filenames are specific to my project; if # you want to use this, you'll have to change them. reverse() { sed class="_tkStr_1klyn_166">'x;class="_tkNum_1klyn_175">1!H;$!d;x' } (echo class="_tkStr_1klyn_166">'rev,python code,unit test,cucumber,media' && git rev-list HEAD | reverse | while read rev; do
2♦
A♦
diff --git a/tests/test_entity.py b/tests/test_entity.py index c3c4aec..8410b9d class="_tkNum_1klyn_175">100644 --- a/tests/test_entity.py +++ b/tests/test_entity.py @@ -class="_tkNum_1klyn_175">209,class="_tkNum_1klyn_175">6 +class="_tkNum_1klyn_175">209,class="_tkNum_1klyn_175">15 @@ class TestMatchesDict(unittest.TestCase): creator=[class="_tkStr_1klyn_166">'Matt', class="_tkStr_1klyn_166">'Nobody'], tags=[class="_tkStr_1klyn_166">'fun', class="_tkStr_1klyn_166">'boring']) == self.e + #def test_order_independence_of_query(self): + # assert not self.e.matches_dict(creator=[class="_tkStr_1klyn_166">'Matt'], + # title=[class="_tkStr_1klyn_166">'DO NOT MATCH']) + # assert not self.e.matches_dict(creator=[class="_tkStr_1klyn_166">'DO NOT MATCH'],
A♦
K♣
The Limits of TDD #date class="_tkNum_1klyn_175">2009-class="_tkNum_1klyn_175">11-class="_tkNum_1klyn_175">09 class="_tkNum_1klyn_175">21:class="_tkNum_1klyn_175">47 #tags python,tdd <p> My <a href=class="_tkStr_1klyn_166">"/class="_tkNum_1klyn_175">2009/class="_tkNum_1klyn_175">11/how_i_started_tdd.html">last post</a> about TDD generated some great responses, some of which were skeptical. A few common complaints about TDD were brought up, and posed with civility, so I'd like to address them. </p> <h4>Complaint: You weren't stupid enough</h4>
K♣
Q♥
failbowl:repo grb$ cloc . class="_tkNum_1klyn_175">1472 text files. class="_tkNum_1klyn_175">1061 unique files. class="_tkNum_1klyn_175">883 files ignored. http:class=class="_tkStr_1klyn_166">"_tkCom_1klyn_170">//cloc.sourceforge.net v class="_tkNum_1klyn_175">1.06 T=class="_tkNum_1klyn_175">36.0 s (class="_tkNum_1klyn_175">11.3 files/s, class="_tkNum_1klyn_175">1457.1 lines/s) -------------------------------------------------------------------------------- Language files blank comment code scale 3rd gen. equiv -------------------------------------------------------------------------------- HTML class="_tkNum_1klyn_175">196 class="_tkNum_1klyn_175">818 class="_tkNum_1klyn_175">14 class="_tkNum_1klyn_175">30174 x class="_tkNum_1klyn_175">1.90 = class="_tkNum_1klyn_175">57330.60 Python class="_tkNum_1klyn_175">169 class="_tkNum_1klyn_175">4155 class="_tkNum_1klyn_175">1517 class="_tkNum_1klyn_175">13664 x class="_tkNum_1klyn_175">4.20 = class="_tkNum_1klyn_175">57388.80 CSS class="_tkNum_1klyn_175">13 class="_tkNum_1klyn_175">120 class="_tkNum_1klyn_175">8 class="_tkNum_1klyn_175">749 x class="_tkNum_1klyn_175">1.00 = class="_tkNum_1klyn_175">749.00
Q♥
J♠
def live_cell_count(x, y): square_coords = [(x-class="_tkNum_1klyn_175">1, y-class="_tkNum_1klyn_175">1), (x+class="_tkNum_1klyn_175">0, y-class="_tkNum_1klyn_175">1), (x+class="_tkNum_1klyn_175">1, y-class="_tkNum_1klyn_175">1), (x-class="_tkNum_1klyn_175">1, y+class="_tkNum_1klyn_175">0), (x+class="_tkNum_1klyn_175">1, y+class="_tkNum_1klyn_175">0), (x-class="_tkNum_1klyn_175">1, y+class="_tkNum_1klyn_175">1), (x+class="_tkNum_1klyn_175">0, y+class="_tkNum_1klyn_175">1), (x+class="_tkNum_1klyn_175">1, y+class="_tkNum_1klyn_175">1)] count = sum(class="_tkNum_1klyn_175">1 for x, y in square_coords if cell_alive_exists(x, y))
J♠
10♦
How would you rather write your tests?
# How would you rather write your tests? # Tell it to @garybernhardt (or gary.bernhardt@gmail.com) # class="_tkNum_1klyn_175">1) Hypothetical RSpec-inspired Python library (PSpec?) that does violence to nature with describe(class="_tkStr_1klyn_166">'my class'): with it(class="_tkStr_1klyn_166">'adds numbers'): sum = MyClass.add(class="_tkNum_1klyn_175">1, class="_tkNum_1klyn_175">1) sum.should == class="_tkNum_1klyn_175">2 # Actually, I think the only acceptable name for the above library would be class="_tkStr_1klyn_166">"withit" # class="_tkNum_1klyn_175">2) Mote (minimal violence to nature) + Expecter Gadget (violence free)
10♦
9♣
# One extra keyword needed for an RSpec clone. Just sayin. describe(class="_tkStr_1klyn_166">'integers') do: it(class="_tkStr_1klyn_166">'can be added') do: expect(class="_tkNum_1klyn_175">1 + class="_tkNum_1klyn_175">1) == class="_tkNum_1klyn_175">2 it(class="_tkStr_1klyn_166">'can be subtracted') do: expect(class="_tkNum_1klyn_175">2 - class="_tkNum_1klyn_175">1) == class="_tkNum_1klyn_175">1 it(class="_tkStr_1klyn_166">'truncates on division') do: expect(class="_tkNum_1klyn_175">3 / class="_tkNum_1klyn_175">2) == class="_tkNum_1klyn_175">1 # Implement blocks with plain old generators: def describe(description): ... set stuff up
9♣
8♥
ls _posts/* | grep -v class="_tkStr_1klyn_166">'[class="_tkNum_1klyn_175">0-class="_tkNum_1klyn_175">9][class="_tkNum_1klyn_175">0-class="_tkNum_1klyn_175">9][class="_tkNum_1klyn_175">0-class="_tkNum_1klyn_175">9][class="_tkNum_1klyn_175">0-class="_tkNum_1klyn_175">9]-[class="_tkNum_1klyn_175">0-class="_tkNum_1klyn_175">9][class="_tkNum_1klyn_175">0-class="_tkNum_1klyn_175">9]-[class="_tkNum_1klyn_175">0-class="_tkNum_1klyn_175">9][class="_tkNum_1klyn_175">0-class="_tkNum_1klyn_175">9]' | while read fn; do day=class="_tkStr_1klyn_166">`grep '#postdate\|#date' $fn | cut -d '-' -f class="_tkNum_1klyn_175">3 | cut -d ' ' -f class="_tkNum_1klyn_175">1`; git mv $fn class="_tkStr_1klyn_166">`echo $fn | sed "s/-\([class="_tkNum_1klyn_175">0-class="_tkNum_1klyn_175">9][class="_tkNum_1klyn_175">0-class="_tkNum_1klyn_175">9]\)-/-\class="_tkNum_1klyn_175">1-$day-/"`; done
8♥
7♠
failbowl:temp $ rm -rf env && pip install -E env dingus && ls -l env/lib/python2.class="_tkNum_1klyn_175">6/site-packages Creating new virtualenv environment in env New python executable in env/bin/python Installing setuptools...done..... Downloading/unpacking dingus Downloading dingus-class="_tkNum_1klyn_175">0.2.tar.gz Running setup.py egg_info for package dingus Installing collected packages: dingus Running setup.py install for dingus warning: build_py: byte-compiling is disabled, skipping. warning: install_lib: byte-compiling is disabled, skipping.
7♠
6♦
failbowl:temp $ rm -rf env && pip install -E env dingus && . env/bin/activate && pip update pip Creating new virtualenv environment in env New python executable in env/bin/python Installing setuptools...done..... Downloading/unpacking dingus Downloading dingus-class="_tkNum_1klyn_175">0.2.tar.gz Running setup.py egg_info for package dingus Installing collected packages: dingus Running setup.py install for dingus warning: build_py: byte-compiling is disabled, skipping. warning: install_lib: byte-compiling is disabled, skipping. Successfully installed dingus
6♦
5♣
failbowl:temp $ deactivate; rm -rf env && pip install -E env dingus && . env/bin/activate && ls -l env/lib/python2.class="_tkNum_1klyn_175">6/site-packages zsh: command not found: deactivate Creating new virtualenv environment in env New python executable in env/bin/python Installing setuptools...done..... Complete output from command /Users/grb/temp/env/bin/python /Users/grb/temp/env/bin/easy_install /opt/local/Library/Frameworks/...ar.gz: Processing pip-class="_tkNum_1klyn_175">0.7.class="_tkNum_1klyn_175">2.tar.gz Running pip-class="_tkNum_1klyn_175">0.7.class="_tkNum_1klyn_175">2/setup.py -q bdist_egg --dist-dir /var/folders/Vr/Vrnubf6zGE4qOl6GIOQjh++++TI/-Tmp-/easy_install-AFWiid/pip-class="_tkNum_1klyn_175">0.7.class="_tkNum_1klyn_175">2/egg-dist-tmp-72Ag6W warning: no files found matching class="_tkStr_1klyn_166">'*.html' under directory class="_tkStr_1klyn_166">'docs' warning: no previously-included files matching class="_tkStr_1klyn_166">'*.txt' found under directory class="_tkStr_1klyn_166">'docs/_build' no previously-included directories found matching class="_tkStr_1klyn_166">'docs/_build/_sources' warning: build_py: byte-compiling is disabled, skipping.
5♣
4♥
failbowl:temp $ pip install -U pip Downloading/unpacking pip Downloading pip-class="_tkNum_1klyn_175">0.7.class="_tkNum_1klyn_175">2.tar.gz (68Kb): 68Kb downloaded Running setup.py egg_info for package pip warning: no files found matching class="_tkStr_1klyn_166">'*.html' under directory class="_tkStr_1klyn_166">'docs' warning: no previously-included files matching class="_tkStr_1klyn_166">'*.txt' found under directory class="_tkStr_1klyn_166">'docs/_build' no previously-included directories found matching class="_tkStr_1klyn_166">'docs/_build/_sources' Installing collected packages: pip Found existing installation: pip class="_tkNum_1klyn_175">0.7.class="_tkNum_1klyn_175">2 Uninstalling pip: Exception: Traceback (most recent call last):
4♥
3♠
whodoneit: Find who introduced a certain pattern to the code base
# Originally from Jonathan Penn, with modifications by Gary Bernhardt function whodoneit() { (set -e && for x in $(git grep -I --name-only $class="_tkNum_1klyn_175">1); do git blame -f -- $x | grep $class="_tkNum_1klyn_175">1; done ) }
3♠
2♦
# This doesn't work – it calls nil.join (the map seems to return nil?) puts things.to_a.sort_by(&:id).map do |thing| class="_tkStr_1klyn_166">"#{thing.id} #{thing.url}" end.join(class="_tkStr_1klyn_166">"\n") # This DOES work (the only difference is that the map uses curlies instead of do/end). puts things.to_a.sort_by(&:id).map { |thing| class="_tkStr_1klyn_166">"#{thing.id} #{thing.url}" }.join(class="_tkStr_1klyn_166">"\n")
2♦
A♦
function wrap(f) return function() -- Storing the result of the wrapped function is the source of the -- problem. result = f() return result end end function f() return class="_tkNum_1klyn_175">1, class="_tkNum_1klyn_175">2 end
A♦
K♣
# Setting up the graph; you can skip to the next comment. $ hg init $ echo class="_tkNum_1klyn_175">0 > class="_tkNum_1klyn_175">0 $ hg ci -Am class="_tkNum_1klyn_175">0 adding class="_tkNum_1klyn_175">0 $ echo class="_tkNum_1klyn_175">1 > class="_tkNum_1klyn_175">1 $ hg ci -Am class="_tkNum_1klyn_175">1 adding class="_tkNum_1klyn_175">1 $ hg co class="_tkNum_1klyn_175">0 class="_tkNum_1klyn_175">0 files updated, class="_tkNum_1klyn_175">0 files merged, class="_tkNum_1klyn_175">1 files removed, class="_tkNum_1klyn_175">0 files unresolved $ echo class="_tkNum_1klyn_175">2 > class="_tkNum_1klyn_175">2 $ hg ci -Am class="_tkNum_1klyn_175">2
K♣
Q♥
# Braintree has a cutesy search query API: class Sweeper def self.sweep! Braintree::Subscription.search do |s| s.status.is Braintree::Subscription::Status::Canceled end end end # Putting expectations on it sucks, but less than I expected: describe Sweeper do it class="_tkStr_1klyn_166">'searches for canceled subscriptions' do
Q♥
J♠
failbowl:destroyallsoftware.com(76m|braintree!?) $ cat Gemfile source class="_tkStr_1klyn_166">'http:class="_tkCom_1klyn_170">//rubygems.org' gem class="_tkStr_1klyn_166">'rails', class="_tkStr_1klyn_166">'class="_tkNum_1klyn_175">3.0.class="_tkNum_1klyn_175">3' # Bundle edge Rails instead: # gem class="_tkStr_1klyn_166">'rails', :git => class="_tkStr_1klyn_166">'git:class="_tkCom_1klyn_170">//github.com/rails/rails.git' gem class="_tkStr_1klyn_166">'sqlite3-ruby', :require => class="_tkStr_1klyn_166">'sqlite3' gem class="_tkStr_1klyn_166">'braintree', class="_tkStr_1klyn_166">'class="_tkNum_1klyn_175">2.7.class="_tkNum_1klyn_175">0' gem class="_tkStr_1klyn_166">'devise', class="_tkStr_1klyn_166">'class="_tkNum_1klyn_175">1.1.class="_tkNum_1klyn_175">5'
J♠
10♦
# I do this: module ActiveRecord class Base @@old_save = instance_method(:save) def save *args @@old_save.bind(self).call *args end end end
10♦
9♣
set conf_name to text returned of ¬ (display dialog ¬ class="_tkStr_1klyn_166">"Enter conference name:" with title ¬ class="_tkStr_1klyn_166">"Schedule Conference" default answer ¬ class="_tkStr_1klyn_166">"" default button class="_tkNum_1klyn_175">2) tell application class="_tkStr_1klyn_166">"Things" set newProject to make new project ¬ with properties {name:conf_name} end tell tell application class="_tkStr_1klyn_166">"Things"
9♣
7♠
$grid_column_width: 40px $grid_column_margin: 10px $grid_columns: class="_tkNum_1klyn_175">12 $grid_width: $grid_columns * ($grid_column_width + $grid_column_margin * class="_tkNum_1klyn_175">2) =container margin-left: auto margin-right: auto width: $grid_width =alpha margin-left: class="_tkNum_1klyn_175">0
7♠
6♦
module Rack module Utils def parse_nested_query(qs, d = nil) params = ActiveSupport::OrderedHash.new (qs || class="_tkStr_1klyn_166">'').split(d ? /[#{d}] */n : DEFAULT_SEP).each do |p| k, v = unescape(p).split(class="_tkStr_1klyn_166">'=', class="_tkNum_1klyn_175">2) normalize_params(params, k, v) end return params end
6♦
5♣
# mock-based (interaction) # db independent, but tied to implementation (I can change the AR call without affecting the behavior and this will fail) context class="_tkStr_1klyn_166">"data gathering" do it class="_tkStr_1klyn_166">"finds all indicators associated with the given sector and includes indicators not associated with any sectors" do sector = stub_model(Sector, :id => class="_tkNum_1klyn_175">6) Indicator.should_receive(:where).with(class="_tkStr_1klyn_166">"sector_id is null or sector_id = ?", sector.id) Indicator.for_sector(sector) end end
5♣
4♥
CantTouchThis = Class.new do def to_s class="_tkStr_1klyn_166">'<CantTouchThis>' end end.new class Stripper def self.strip(klass) klass.class_eval do Stripper::constants_to_remove.each do |c| self.const_set c.to_sym, CantTouchThis end
4♥
3♠
Given /^I'm subscribed as a group host for ([^ ]*) users?$/ do |users| users = users.to_i steps %Q{ Given I'm on the account page Given I enter valid billing details } choose(class="_tkStr_1klyn_166">"for_many") # THIS FAILS fill_in class="_tkStr_1klyn_166">"people ($class="_tkNum_1klyn_175">9 per month each)", :with => users steps(class="_tkStr_1klyn_166">'And I press "Subscribe"') end
3♠
2♦
Before/after let comparison
class Delegator takes :request, :route_path, :resource, :delegate_name let(:delegate_method) { @resource.record_class.method(method_name) } let(:method_name) { @delegate_name.split(class="_tkStr_1klyn_166">'.').last.to_sym } def delegate delegate_method.call(*delegate_args) end def delegate_args inference_sources = InferenceSources.new(@request,
2♦
A♦
PyCodeConf 2011 Lightning Talk Signup
I want to give a lightning talk about: class="_tkStr_1klyn_166">"Wat?" I need the projector: yes / no Yes
A♦
K♣
require class="_tkStr_1klyn_166">'download_policy' describe DownloadPolicy do let(:screencast) { stub(:free? => false) } let(:anonymous_user) { nil } let(:user_with_access) { stub(:has_screencast_access? => true) } let(:user_without_access) { stub(:has_screencast_access? => false) } it class="_tkStr_1klyn_166">"is disallowed for anonymous users" do subject.allow_download_for?(screencast, anonymous_user).should be_false end
K♣
Q♥
# Make a user that we'll add a book to. user = User.create! controller.stub(:current_user) { user } # This prints []. The book list is empty. p user.books # Expect a book to be added to the user. This fails (see below) expect { post :create, :id => asin }.to change { user.books }.from([]).to([book])
Q♥
J♠
Python array methods: >>> [m for m in dir([]) if not m.startswith(class="_tkStr_1klyn_166">"_")] [class="_tkStr_1klyn_166">'append', class="_tkStr_1klyn_166">'count', class="_tkStr_1klyn_166">'extend', class="_tkStr_1klyn_166">'index', class="_tkStr_1klyn_166">'insert', class="_tkStr_1klyn_166">'pop', class="_tkStr_1klyn_166">'remove', class="_tkStr_1klyn_166">'reverse', class="_tkStr_1klyn_166">'sort'] Ruby array methods: >> ([].methods - Object.methods).sort => [class="_tkStr_1klyn_166">"&", class="_tkStr_1klyn_166">"*", class="_tkStr_1klyn_166">"+", class="_tkStr_1klyn_166">"-", class="_tkStr_1klyn_166">"<<", class="_tkStr_1klyn_166">"[]", class="_tkStr_1klyn_166">"[]=", class="_tkStr_1klyn_166">"all?", class="_tkStr_1klyn_166">"any?", class="_tkStr_1klyn_166">"assoc", class="_tkStr_1klyn_166">"at", class="_tkStr_1klyn_166">"choice", class="_tkStr_1klyn_166">"clear", class="_tkStr_1klyn_166">"collect", class="_tkStr_1klyn_166">"collect!", class="_tkStr_1klyn_166">"combination", class="_tkStr_1klyn_166">"compact", class="_tkStr_1klyn_166">"compact!", class="_tkStr_1klyn_166">"concat", class="_tkStr_1klyn_166">"count", class="_tkStr_1klyn_166">"cycle", class="_tkStr_1klyn_166">"delete", class="_tkStr_1klyn_166">"delete_at", class="_tkStr_1klyn_166">"delete_if", class="_tkStr_1klyn_166">"detect",
J♠
10♦
# Rails controller def create @profile = ProfileManager.create(params[:profile]) rescue ProfileManager::CreationFailed => e render :new, :errors => e.errors end # Raptor route create :to => class="_tkStr_1klyn_166">"ProfileManager#create", ProfileManager::CreationFailed => render(:new)
10♦
9♣
# Hash form: { :current_user => class="_tkStr_1klyn_166">"CurrentUser.current_user" } # Discovery form with inverted app structure: module Injectables def current_user(session) User.find(:id => session[class="_tkStr_1klyn_166">'current_user_id']) end end
9♣
8♥
Last login: Mon Jan class="_tkNum_1klyn_175">30 class="_tkNum_1klyn_175">16:class="_tkNum_1klyn_175">54:class="_tkNum_1klyn_175">38 on ttys000 failbowl:~(master!?) $ rvm install ree Installing Ruby Enterprise Edition from source to: /Users/grb/.rvm/rubies/ree-class="_tkNum_1klyn_175">1.8.class="_tkNum_1klyn_175">7-class="_tkNum_1klyn_175">2011.12 ree-class="_tkNum_1klyn_175">1.8.class="_tkNum_1klyn_175">7-class="_tkNum_1klyn_175">2011.12 - #fetching (ruby-enterprise-class="_tkNum_1klyn_175">1.8.class="_tkNum_1klyn_175">7-class="_tkNum_1klyn_175">2011.12) % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed class="_tkNum_1klyn_175">100 7773k class="_tkNum_1klyn_175">100 7773k class="_tkNum_1klyn_175">0 class="_tkNum_1klyn_175">0 2447k class="_tkNum_1klyn_175">0 class="_tkNum_1klyn_175">0:class="_tkNum_1klyn_175">00:class="_tkNum_1klyn_175">03 class="_tkNum_1klyn_175">0:class="_tkNum_1klyn_175">00:class="_tkNum_1klyn_175">03 --:--:-- 2513k ree-class="_tkNum_1klyn_175">1.8.class="_tkNum_1klyn_175">7-class="_tkNum_1klyn_175">2011.12 - #extracting ruby-enterprise-class="_tkNum_1klyn_175">1.8.class="_tkNum_1klyn_175">7-class="_tkNum_1klyn_175">2011.12 to /Users/grb/.rvm/src/ree-class="_tkNum_1klyn_175">1.8.class="_tkNum_1klyn_175">7-class="_tkNum_1klyn_175">2011.12 Applying patch class="_tkStr_1klyn_166">'tcmalloc' (located at /Users/grb/.rvm/patches/ree/class="_tkNum_1klyn_175">1.8.class="_tkNum_1klyn_175">7/tcmalloc.patch) Applying patch class="_tkStr_1klyn_166">'stdout-rouge-fix' (located at /Users/grb/.rvm/patches/ree/class="_tkNum_1klyn_175">1.8.class="_tkNum_1klyn_175">7/stdout-rouge-fix.patch) Applying patch class="_tkStr_1klyn_166">'no_sslv2' (located at /Users/grb/.rvm/patches/ree/class="_tkNum_1klyn_175">1.8.class="_tkNum_1klyn_175">7/no_sslv2.diff) Applying patch class="_tkStr_1klyn_166">'lib64' (located at /Users/grb/.rvm/patches/ree/lib64.patch)
8♥
7♠
#!/bin/ruby guard class="_tkStr_1klyn_166">'spork' do watch(%r{^config/.*\.rb$}) watch(%r{^config/environments/.*\.rb$}) watch(%r{^config/initializers/.*\.rb$}) watch(%r{^features/support/.*\.rb$}) watch(class="_tkStr_1klyn_166">'spec/spec_helper.rb') end
7♠
6♦
failbowl:temp(master+!?) $ git st # On branch master # Changes to be committed: # (use class="_tkStr_1klyn_166">"git reset HEAD <file>..." to unstage) # # modified: a # new file: c # # Changes not staged for commit: # (use class="_tkStr_1klyn_166">"git add <file>..." to update what will be committed) # (use class="_tkStr_1klyn_166">"git checkout -- <file>..." to discard changes in working directory) #
6♦
5♣
describe class="_tkStr_1klyn_166">'a' do it class="_tkStr_1klyn_166">"raises an error when no source is found for an argument" do klass = Class.new { def f(unknown_argument); end } expect do injector.call(klass.new.method(:f)) end.to raise_error(Syringe::UnknownInjectable) end end
5♣
4♥
I asked Comcast to stop leaving me two four-second voice mails every day. This is their response.
Dear Gary, Thank you for contacting Comcast Email Support. My name is Jean and I appreciate your time and effort in contacting us. I hope you are having a great day. I understand that you would like us to put your name and your number, xxx-xxx-xxxx, right at this moment. I truly understand how this must have been frustrating to you and I do apologize for any inconvenience this has caused you. I can certainly understand how important it is for you to have this resolved as soon as possible in order for you to not receive any call. Rest assured that we, at Comcast, are dedicated to
4♥
3♠
def tweet(o) match(o) { with(o.name == class="_tkStr_1klyn_166">"garybernhardt") { raise TrollError } with(Image i) { tweet ShortLink.for_image(i) } with(Text t) { actually_tweet_here } } end
3♠
2♦
class Changes < Actor out :timeline_tweets_out takes :tweets_in, :friends_in def before @friends = @friends_in.pop end def pump tweet = @tweets_in.pop timeline_tweets_out << tweet if @friends.include_user?(tweet.user) end
2♦
A♦
Isolation, Data & Dependencies
Isolated unit testing—mocking everything—is a controversial topic. We'll briefly review what it is today, why people like it, and its problems. Then, on to the real goal: a trip through behavior vs. data, mutation vs. immutability, how data shape affords parallelism, transforming interface dependencies into data dependencies, and what it might look like to unify all of these with a slightly tweaked version of OO. Fortunately, Ruby is sufficiently flexible that we can do the whole experiment without leaving it.
A♦
K♣
A Whole New World Few of us have participated in the creation of our infrastructure—operating systems, compilers, terminals, editors, etc., even though many of us know how to build them in theory. Collectively, we suffer from a learned helplessness around them: to build new high-level tools, we'd also have to rebuild some of the infrastructure, sometimes going all the way down to the kernel. We can't imagine triggering such a large cultural and technological shift, so we don't even try to build truly new tools for ourselves. Iclass="_tkStr_1klyn_166">'ve been working on such a stack-busting tool and, though I won't spill the beans on it here, Iclass="_tkStr_1klyn_166">'ll say that it's required me to
K♣
Q♥
#define assert_equals(expected, actual)\ if (expected != actual) {\ printf(class="_tkStr_1klyn_166">"FAIL: %#Lx != %#Lx\n", (uint64_t)expected, (uint64_t)actual);\ exit(class="_tkNum_1klyn_175">1); \ } #define run_test(name)\ printf(class="_tkStr_1klyn_166">"%s\n", #name);\ name();
Q♥
J♠
tell application class="_tkStr_1klyn_166">"Finder" open file ((path to home folder as text) & class="_tkStr_1klyn_166">"Dropbox:notes") using ((path to applications folder as text) & class="_tkStr_1klyn_166">"MacVim.app") end tell tell application class="_tkStr_1klyn_166">"MacVim" activate end tell
J♠
10♦
failbowl:~(master!?) $ # Curl with normal user agent; get the correct text back failbowl:~(master!?) $ curl -s class="_tkStr_1klyn_166">'https:class="_tkCom_1klyn_170">//gist.github.com/raw/class="_tkNum_1klyn_175">4534954/b508396cb255b52a0defbc75c92e69ad5c2937b5/gistfile1.rb' | head -class="_tkNum_1klyn_175">1 # I don't really see any services here. What I see is: failbowl:~(master!?) $ # Curl as iPhone; get broken text back failbowl:~(master!?) $ curl -s -A class="_tkStr_1klyn_166">'Mozilla/class="_tkNum_1klyn_175">5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/class="_tkNum_1klyn_175">528.18 (KHTML, like Gecko) Version/class="_tkNum_1klyn_175">4.0 Mobile/7A341 Safari/class="_tkNum_1klyn_175">528.16' class="_tkStr_1klyn_166">'https:class="_tkCom_1klyn_170">//gist.github.com/raw/class="_tkNum_1klyn_175">4534954/b508396cb255b52a0defbc75c92e69ad5c2937b5/gistfile1.rb' | head -class="_tkNum_1klyn_175">1 # I don&#class="_tkNum_1klyn_175">39;t really see any services here. What I see is:
10♦
9♣
failbowl:~(master) $ irb >> X = class="_tkNum_1klyn_175">1 => class="_tkNum_1klyn_175">1 >> undef_const :X NoMethodError: undefined method `undef_const' for main:Object from (irb):class="_tkNum_1klyn_175">2 >> const_undef :X NoMethodError: undefined method `const_undef' for main:Object from (irb):class="_tkNum_1klyn_175">3 >> const_delete :X NoMethodError: undefined method `const_delete' for main:Object from (irb):class="_tkNum_1klyn_175">4
9♣
8♥
>> class Foo; attr_accessor :hello; end >> f = Foo.new >> f.hello = lambda { puts class="_tkStr_1klyn_166">"why no self?" } >> f.hello => #<Proc:0x0000000102b6e768@(irb):class="_tkNum_1klyn_175">12>
8♥
7♠
--- /Users/grb/.rvm/gems/ruby-class="_tkNum_1klyn_175">1.9.class="_tkNum_1klyn_175">3-p194@investments/gems/values-class="_tkNum_1klyn_175">1.5.class="_tkNum_1klyn_175">0/lib/values.rb class="_tkNum_1klyn_175">2013-class="_tkNum_1klyn_175">06-class="_tkNum_1klyn_175">17 class="_tkNum_1klyn_175">19:class="_tkNum_1klyn_175">28:class="_tkNum_1klyn_175">23.000000000 -class="_tkNum_1klyn_175">0700 +++ values.rb class="_tkNum_1klyn_175">2013-class="_tkNum_1klyn_175">06-class="_tkNum_1klyn_175">25 class="_tkNum_1klyn_175">17:class="_tkNum_1klyn_175">28:class="_tkNum_1klyn_175">17.000000000 -class="_tkNum_1klyn_175">0700 @@ -class="_tkNum_1klyn_175">1,class="_tkNum_1klyn_175">7 +class="_tkNum_1klyn_175">1,class="_tkNum_1klyn_175">7 @@ class Value def self.new(*fields) Class.new do - attr_reader *fields + attr_reader :hash, *fields define_method(:initialize) do |*values| raise ArgumentError.new(class="_tkStr_1klyn_166">"wrong number of arguments, #{values.size} for #{fields.size}") if fields.size != values.size @@ -class="_tkNum_1klyn_175">10,class="_tkNum_1klyn_175">6 +class="_tkNum_1klyn_175">10,class="_tkNum_1klyn_175">8 @@
7♠
6♦
thelongpoll: Acquiring lock on /Users/grb/.thelongpoll thelongpoll: - Got it thelongpoll: Is the mail client running? thelongpoll: * ps aux thelongpoll: - No thelongpoll: Checking git status thelongpoll: * (cd /Users/grb/Downloads/Gmail && git status --short) thelongpoll: - Clean thelongpoll: Don't need to commit to git thelongpoll: Starting sync thelongpoll: * offlineimap OfflineIMAP class="_tkNum_1klyn_175">6.5.class="_tkNum_1klyn_175">4
6♦
5♣
John Carmack on shadow volumes... I recieved this in email from John on May 23rd, class="_tkNum_1klyn_175">2000. - Mark Kilgard I solved this in a way that is so elegant you just won't believe it. Here is a description that I posted to a private mailing list: ----------------------------------------------------------
5♣
4♥
$ echo class="_tkStr_1klyn_166">'#!/bin/ls /' > foo $ ./foo ./foo /: bin boot dev etc home initrd.img lib lib64 lost+found media mnt opt proc root run sbin selinux srv sys tmp usr var vmlinuz $ echo class="_tkStr_1klyn_166">'#!/bin/ls / /' > foo $ ./foo /bin/ls: cannot access / /: No such file or directory
4♥
3♠
#!/bin/bash /usr/bin/env ruby --disable-gems <(cat <<class="_tkStr_1klyn_166">'EOF' puts class="_tkStr_1klyn_166">"ruby code goes here" EOF)
3♠
2♦
failbowl:~(master) $ cabal list --installed hunit class=class="_tkStr_1klyn_166">"_tkCom_1klyn_170">* HUnit Synopsis: A unit testing framework for Haskell Default available version: class="_tkNum_1klyn_175">1.2.class="_tkNum_1klyn_175">5.2 Installed versions: class="_tkNum_1klyn_175">1.2.class="_tkNum_1klyn_175">5.2 Homepage: http:class=class="_tkStr_1klyn_166">"_tkCom_1klyn_170">//hunit.sourceforge.net/ License: BSD3 failbowl:~(master) $ echo class="_tkStr_1klyn_166">'import HUnit' | runhaskell /var/folders/g5/jl_jnwv57nn_rhnvd_v6wpqw0000gn/T/runghcXXXX79850.hs:class="_tkNum_1klyn_175">1:class="_tkNum_1klyn_175">8: Could not find module `HUnit'
2♦
A♦
puts class="_tkStr_1klyn_166">"export #{vars.map { |k, v| %{#{k}="#{v}class="_tkStr_1klyn_166">"} }.join(" class="_tkStr_1klyn_166">")}"
A♦
K♣
failbowl:rubies(master) $ git l class=class="_tkStr_1klyn_166">"_tkCom_1klyn_170">* 65cc7ef (class="_tkNum_1klyn_175">41 seconds) <Gary Bernhardt> (HEAD, master) Merge branch class="_tkStr_1klyn_166">'activate_command_cleanup' |\ | * f4ced72 (class="_tkNum_1klyn_175">2 minutes) <Gary Bernhardt> extract variables | * f2760be (class="_tkNum_1klyn_175">3 minutes) <Gary Bernhardt> File.join instead of string interpolation | * 94b8df5 (class="_tkNum_1klyn_175">5 minutes) <Gary Bernhardt> activate command's imperative part is in activate! |/ class=class="_tkStr_1klyn_166">"_tkCom_1klyn_170">* class="_tkNum_1klyn_175">9291243 (class="_tkNum_1klyn_175">7 minutes) <Gary Bernhardt> Merge branch class="_tkStr_1klyn_166">'ruby_info_cleanup' |\ | * b7cb944 (class="_tkNum_1klyn_175">9 minutes) <Gary Bernhardt> indentation | * a3428c7 (class="_tkNum_1klyn_175">10 minutes) <Gary Bernhardt> move RubyInfo field extraction into RubyInfo class | * dff6a33 (class="_tkNum_1klyn_175">15 minutes) <Gary Bernhardt> introduce ruby_info! command method
K♣
Q♥
it class="_tkStr_1klyn_166">"requires an amount_charged greater than class="_tkNum_1klyn_175">0" do order = FactoryGirl.build(:order, :amount_charged => class="_tkNum_1klyn_175">0) order.valid?.should == false order.errors[:amount_charged].should == [class="_tkStr_1klyn_166">"must be greater than class="_tkNum_1klyn_175">0"] end
Q♥
J♠
git diff --name-status head~class="_tkNum_1klyn_175">3000..head | grep class="_tkStr_1klyn_166">'^D' | awk class="_tkStr_1klyn_166">'{print $class="_tkNum_1klyn_175">2}' | while read f; do git log -class="_tkNum_1klyn_175">1 --pretty=class="_tkStr_1klyn_166">"format:%H" -- class="_tkStr_1klyn_166">"$f"; done > temp.txt
J♠
10♦
def adjust(t,h);(class="_tkNum_1klyn_175">3*h)−(class="_tkNum_1klyn_175">4*t*h);end def adjust(t,h);(class="_tkNum_1klyn_175">3*h)-(class="_tkNum_1klyn_175">4*t*h);end
10♦
9♣
CyBurTaz: i programed my comps memory to read my own lang RAVERgrl34: LoL... oh muh god! CyBurTaz: FOXXY STFU RAVERgrl34: you are a piece of shit! RAVERgrl34: ROFL RAVERgrl34: LMAO RAVERgrl34: oh muh god! RAVERgrl34: you are lamest mother fucking i have ever seen! RAVERgrl34: oh muh god, you are lame.
9♣
8♥
failbowl:~(master) $ curl class="_tkStr_1klyn_166">'http:class="_tkCom_1klyn_170">//maps.google.com/?saddr=St.%20Petersburg%20Shavrova%class="_tkNum_1klyn_175">2015&daddr=St.%20Petersburg%20Sadovaya%class="_tkNum_1klyn_175">2030&dirflg=r&output=json' <HTML><HEAD><meta http-equiv=class="_tkStr_1klyn_166">"content-type" content=class="_tkStr_1klyn_166">"text/html;charset=utf-class="_tkNum_1klyn_175">8"> <TITLE>class="_tkNum_1klyn_175">302 Moved</TITLE></HEAD><BODY> <H1>class="_tkNum_1klyn_175">302 Moved</H1> The document has moved <A HREF=class="_tkStr_1klyn_166">"http:class="_tkCom_1klyn_170class="_tkStr_1klyn_166">">//maps.google.com/maps?saddr=St.%20Petersburg%20Shavrova%class="_tkNum_1klyn_175">2015&daddr=St.%20Petersburg%20Sadovaya%class="_tkNum_1klyn_175">2030&dirflg=r&output=json">here</A>. </BODY></HTML> failbowl:~(master) $ curl class="_tkStr_1klyn_166">'http:class="_tkCom_1klyn_170">//maps.google.com/maps?saddr=St.%20Petersburg%20Shavrova%class="_tkNum_1klyn_175">2015&daddr=St.%20Petersburg%20Sadovaya%class="_tkNum_1klyn_175">2030&dirflg=r&output=json' <HTML><HEAD><meta http-equiv=class="_tkStr_1klyn_166">"content-type" content=class="_tkStr_1klyn_166">"text/html;charset=utf-class="_tkNum_1klyn_175">8"> <TITLE>class="_tkNum_1klyn_175">302 Moved</TITLE></HEAD><BODY> <H1>class="_tkNum_1klyn_175">302 Moved</H1>
8♥
7♠
$ heroku pg:backups Installing Heroku Toolbelt v4... done. For more information on Toolbelt v4: https:class=class="_tkStr_1klyn_166">"_tkCom_1klyn_170">//github.com/heroku/heroku-cli Setting up node-v4.class="_tkNum_1klyn_175">1.1... done Installing core plugins heroku-cli-addons, heroku-apps, heroku-fork, heroku-git, heroku-local, heroku-run, heroku-status... ▸ Error reading plugin: heroku-apps. See /Users/grb/.heroku/error.log for more information. Error reading plugin: heroku-cli-addons. See /Users/grb/.heroku/error.log for more information. Error reading plugin: heroku-fork. See /Users/grb/.heroku/error.log for more information. Error reading plugin: heroku-git. See /Users/grb/.heroku/error.log for more information. Error reading plugin: heroku-local. See /Users/grb/.heroku/error.log for more information. Error reading plugin: heroku-run. See /Users/grb/.heroku/error.log for more information.
7♠
6♦
from collections import namedtuple from datetime import date # Here's a user defined using the usual class="_tkStr_1klyn_166">"OO" style. class UserClass: def __init__(self, first, last, birthday): self.__first = first self.__last = last self.__birthday = birthday def name(self): return self.__first + class="_tkStr_1klyn_166">" " + self.__last
6♦