Here[1] is a nice breakdown of Zippers in Clojure. I am not the author of the post but I found it very helpful when I wanted to learn more about Zippers in Clojure. There are some nice illustrations as well.
Pry provides most of the value, so my script is usually basically just something like this:
def reload
load "app.rb"
# If you want to load multiple files, remember that if app.rb
# uses require/require relative, the files will only be loaded
# once; you can change that but really it's not usually what
# you want for production; in that case either look into a proper
# reloader, or you'll want to load the rest of the files here.
# Sometimes it's fine to e.g. do a Dir.glob("*.rb").each {load _1}.
load "dev.rb"
# Put "dev niceties" in this file. E.g. maybe load table_print or
# awesome_print, Hirb, or whichever nice formatting tools you
# want, or define any custom introspection methods that are
# helpful. Eg. for an analytics project I worked on had a few tools to
# wrangle CSV test data there. (I really ought to extract the best
# from my various projects into a gist or something, but these
# files often accumulate really project-specific stuff.
end
require 'pry'
reload
binding.pry # Throws you in the Pry prompt at the top level scope.
It does require that you're somewhat careful not to make the loading of your files too stateful, which is a good practice anyway, and you do need to be mindful that things will occasionally fall apart if you reload the running code as it will modify the classes of objects that already exists but not e.g. update their instance variables, so if you add a method that expects @foo to have been initialized, but existing objects do not have it initialized, things will go obviously go badly.
Since pry supports "edit some_method_name" and will spawn $EDITOR you can even do edits in the same terminal that way, but I tend to prefer to have my editor open in another window. (And since so many here seems to struggle to find methods, in addition to "edit", "show-method some_method" in the right context in pry is also highly useful)
Sometimes I'll keep ways to trigger pry in applications during regular runtime because it's so useful for debugging issues, and sometimes even fixing issues in a running process.
EDIT: While I prefer pry, it's worth noting that Irb has gotten a lot better (lots of features from pry) in recent versions, and also "rdbg" (debug gem) is awesome if you don't want to use a separate script like this - you can equally well run your code under rdbg and just have a script handy to load tools you want for a debug session; the downside of rdbg is if e.g. attaching remotely you'll be running in a trap context, which means you don't have quite the same freedom with respect to what code you can actually run - that may or may not matter.
mruby[1] fits that category too. It can be used with H2O[2] server as well. There was a discussion here a couple of months ago regarding some use cases[3].
When I started using Paredit I found "The Animated Guide to Paredit"[1] very helpful. It basicaly demonastrates some of the most useful commands in short videos.
> I want something much simpler, so I use VS code with a "REST Client" plugin
I follow the same approach. Emacs, Verb[0] and org-mode. An alternative to Verb would be restclient.el[1] but I like Verb more because it works as an extension to org-mode which is great for documentation.
No news about Ractors! The new concurrency facilities that Ruby 3.0 introduced. Anyone has an insight if there was any further development on that front?
"By default, all C extensions are recognized as Ractor-unsafe. If C extension becomes Ractor-safe, the extension should call `rb_ext_ractor_safe(true)` at the `Init_` function and all defined method marked as Ractor-safe. Ractor-unsafe C-methods only been called from main-ractor. If non-main ractor calls it, then `Ractor::UnsafeError` is raised."
I've submitted a few such patches for my own personal use, and it's a very trivial change for extensions which keep no state in C-land that would need to be synchronized between Ractors, e.g. https://github.com/dearblue/ruby-extattr/pull/1
- https://grishaev.me/en/clojure-zippers/