Skip to content

Instantly share code, notes, and snippets.

@kddnewton
kddnewton / gems.rb
Last active March 15, 2023 17:02
Extract the latest versions of each Ruby gem on your system
# frozen_string_literal: true
require "rubygems/package"
require "net/http"
require "tmpdir"
queue = Queue.new
Gem::SpecFetcher.new.available_specs(:latest).first.each do |source, gems|
gems.each do |tuple|
gem_name = File.basename(tuple.spec_name, ".gemspec")
@kddnewton
kddnewton / index.rb
Last active December 22, 2022 20:42
Indexing classes/modules/methods
#!/usr/bin/env ruby
# frozen_string_literal: true
VM_DEFINECLASS_TYPE_CLASS = 0x00
VM_DEFINECLASS_TYPE_SINGLETON_CLASS = 0x01
VM_DEFINECLASS_TYPE_MODULE = 0x02
VM_DEFINECLASS_FLAG_SCOPED = 0x08
VM_DEFINECLASS_FLAG_HAS_SUPERCLASS = 0x10
def log(line, event, message)
@kddnewton
kddnewton / emoji.rb
Created December 1, 2022 15:11
Emoji encoding
def c2e(string) = string.chars.map { |char| [char.ord + 128000].pack("U") }.join
def e2c(string) = string.unpack("U*").pack("c*")
c2e("Hello, world!")
# => "👈👥👬👬👯🐬🐠👷👯👲👬👤🐡"
e2c("👈👥👬👬👯🐬🐠👷👯👲👬👤🐡")
# => "Hello, world!"
e2c(c2e("Hello, world!"))
@kddnewton
kddnewton / count.rb
Created November 28, 2022 21:50
Count the number of YARV instructions in source
def count(iseq)
iseq[12].select { _1 in [:ensure | :rescue, *] }.sum { count(_1[1]) } +
iseq[13].sum do
case _1
in Integer | Symbol
0
in [*, ["YARVInstructionSequence/SimpleDataFormat", *] => child, *]
1 + count(child)
in Array
1
@kddnewton
kddnewton / linter.rb
Created November 9, 2022 20:17
Linting with Syntax Tree
# frozen_string_literal: true
module SyntaxTree
# This class is used to create a mutation that transforms syntax trees based
# on various linting rules.
class Linter
def mutation
SyntaxTree.mutation do |mutator|
# Lint/AssignmentInCondition
mutator.mutate("IfNode[predicate: Assign | OpAssign] | UnlessNode[predicate: Assign | OpAssign] | WhileNode[predicate: Assign | OpAssign] | UntilNode[predicate: Assign | OpAssign]") do |node|
@kddnewton
kddnewton / mutation.rb
Created November 8, 2022 20:22
Mutation visitor
require "syntax_tree"
# Create a new visitor that is going to visit the parsed tree.
visitor = SyntaxTree::Visitor::MutationVisitor.new
# Define a mutation on the visitor that is going to search for the given pattern
# to find nodes that match it and then call the given block to mutate the node
# in place in the tree.
visitor.mutate("If[predicate: Assign | OpAssign]") do |node|
# Get the existing If's predicate node.
@kddnewton
kddnewton / latexify.rb
Last active November 7, 2022 14:45
LaTeXify Ruby methods
#!/usr/bin/env ruby
# frozen_string_literal: true
require "bundler/inline"
gemfile do
source "https://rubygems.org"
gem "syntax_tree"
end
@kddnewton
kddnewton / pattern.rb
Created November 1, 2022 21:52
More pattern matching
# Imagine we need to switch on some kind of input and do something based on some
# attribute of that input. We can do this with a case statement, where we inline
# each of the implementations of the interface that we're defining into the case
# statement. That would look something like:
class Input
attr_reader :type, :name
def initialize(type, name)
@type = type
@kddnewton
kddnewton / pattern.rb
Created October 28, 2022 15:07
Pattern matching
# This module is a light implementation of pattern matching that allows us to
# match against hashes and arrays as we would with the new pattern matching
# syntax.
module Pattern
class ArrayPattern
attr_reader :values
def initialize(values)
@values = values
end
@kddnewton
kddnewton / test.rb
Created September 30, 2022 16:58
Minitest example
require "minitest/autorun"
class TemplatingTest < Minitest::Test
def test_positional_argument_splats
assert_templates <<~RUBY, "h1", "*args"
@_target << "<h1>" << _output(*args) << "</h1>"
RUBY
end
def test_multiple_positional_argument_splats