havenwood

Activity Graph

Page 1 of 212 | Next »

2019-01-20

[20:57:35] havenwood: LunarDinosaur: If you're using a version of Ruby <2.6, be sure to: gem install bundler
[20:58:14] havenwood: blackmesa: Three different databases or three apps sharing the same database?
[21:08:25] havenwood: nir0, oh, they left. Anyways, `User.where.first` is different than `User.where({}).first`.
[21:15:22] havenwood: blackmesa: 👍🏽
[21:19:20] havenwood: blackmesa: Are you using SCLo software collections?
[21:19:23] havenwood: blackmesa: They have a Ruby 2.5 package for CentOS: https://www.softwarecollections.org/en/scls/rhscl/rh-ruby25/
[21:19:51] havenwood: blackmesa: These days, the Rails default is Puma.
[21:20:25] havenwood: No, it's for all env.
[21:21:20] havenwood: We use Puma in prod widely, though we also use Passenger still on some services.
[21:21:59] havenwood: blackmesa: It's similar to Phusion Passenger's standalone mode. It doesn't have Nginx/Apache modules.
[21:22:51] havenwood: yes, it's quite common to reverse proxy from Nginx to Puma.
[21:23:21] havenwood: just point Nginx at the socket that Puma is running on
[21:26:32] havenwood: blackmesa: CentOS choosing a sudo location for gem installs can be worked around if you want. Or you could use ruby-install without chruby.
[21:26:45] havenwood: blackmesa: It's simpler to setup Puma ¯\_(ツ)_/¯
[21:27:21] havenwood: blackmesa: CentOS happens to choose a $GEM_HOME outside your home dir.
[21:27:45] havenwood: blackmesa: gem has a `--user-install` flag that would override CentOS default
[21:27:57] havenwood: blackmesa: --[no-]user-install Install in user's home directory instead of GEM_HOME.
[21:28:26] havenwood: blackmesa: Or you can just use the CentOS default, and use sudo. Your preference!
[21:31:00] havenwood: why the CentOS change?
[21:31:47] havenwood: can you go to Fedora instead? :P they have a nice Ruby package like FreeBSD
[21:32:46] havenwood: I'd probably try to get the CentOS Ruby 2.5 package working with Nginx and Puma. If that didn't work, I'd ruby-install, setup chruby, then hardcode the env vars and ditch chruby.
[21:33:01] havenwood: blackmesa: https://github.com/postmodern/ruby-install
[21:33:20] havenwood: https://github.com/postmodern/chruby
[21:33:22] havenwood: blackmesa: np, gl!
[21:46:07] havenwood: blackmesa: fwiw, if you want to compile Ruby 2.6 from source, then set env vars like chruby would, here's what I think it'd take: https://gist.github.com/havenwood/2de8bdaed96e787814adf2662cc8cd0f
[21:46:46] havenwood: threw in jemalloc for good fun :) it does tend to keep memory usage down and speed things up a bit to boot
[21:49:21] havenwood: what stopped you?
[21:53:01] havenwood: blackmesa: yes
[21:53:30] havenwood: blackmesa: just because the --prefix location would be in a user directory: https://gist.github.com/havenwood/2de8bdaed96e787814adf2662cc8cd0f#file-blackmesa-sh-L5
[21:54:08] havenwood: blackmesa: it would require sudo if you put it in a system dir, like: --prefix=/opt/rubies/ruby-2.6.0
[21:55:01] havenwood: blackmesa: just setting those env vars is all it takes to configure it as the default Ruby and make gem executables available
[21:55:20] havenwood: you can leave system Ruby around if you want - it wouldn't conflict
[21:56:54] havenwood: blackmesa: updated the gist with a nit (sudo isn't required for `make install` with a user dir
[21:57:41] havenwood: blackmesa: if you change the 2.6s to 2.5s and the 2.6.0s to 2.5.3s the same script should work for 2.5.3
[21:58:26] havenwood: blackmesa: or this is what ruby-install would do with: ruby-install ruby-2.6.0 -- --with-jemalloc
[21:59:20] havenwood: and the env vars are what chruby would set with: chruby ruby-2.6.0
[22:03:46] havenwood: blackmesa: that makes sense! the first TEENY release is usually a good time to bump.
[22:04:26] havenwood: i'd imagine it won't be too long 'till 2.6.1

2019-01-19

[17:58:14] havenwood: desperek: Camping was a neat project by _why, but I agree there are crisper options these days unless you're just exploring.
[17:59:15] havenwood: desperek: If you'd like something Rails-ish, checkout Hanami. Or if you'd like something simple that's extensible, +1 Roda.
[17:59:25] havenwood: desperek: https://hanamirb.org/
[17:59:32] havenwood: desperek: http://roda.jeremyevans.net/
[18:01:35] havenwood: desperek: Many folk use Sequel with Roda. Sequel and ActiveRecord are the two most popular Ruby ORMs by far.
[18:02:11] havenwood: desperek: Like Roda, Sequel uses a plugin pattern. Its base is simple, but you can use plugins to compose the ORM you need.
[18:02:25] havenwood: desperek: In Roda, the base is simple and you use plugins to compose the framework you need.
[18:02:45] havenwood: desperek: https://sequel.jeremyevans.net/
[18:03:31] havenwood: desperek: If you'd like more rails, Hanami has a defined pattern: https://guides.hanamirb.org/repositories/sql-queries/
[18:04:12] havenwood: i do like that path. it's fun to write all the code yourself and keep it tiny.
[18:14:59] havenwood: desperek: All Rack apps have a config.ru file (rackup file), even Rails. Typically in a Roda app you'll start with config.ru that uses the Roda app from an app.rb.
[18:15:06] havenwood: desperek: you're right, it doesn't really matter.
[23:39:58] havenwood: hightower2: File.expand_path(__FILE__)
[23:41:24] havenwood: lupine: If you change the working directory, Dir.pwd won't be the dir the file is in anymore, so Ii think it's better to use `File.expand_path(__dir__)` and `File.expand_path(__FILE__)`.

2019-01-18

[22:44:42] havenwood: ACTION chants sloth! sloth! sloth!

2019-01-17

[17:27:08] havenwood: RougeRR: Yes, that sounds convoluted. I can't think of an example where multiple if statements on a single line would be readable.
[18:39:45] havenwood: gpg2 --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
[18:39:45] havenwood: norayr: Add the new key as well:
[18:40:00] havenwood: norayr: the latest is signed with 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
[18:40:08] havenwood: norayr: see: https://rvm.io/
[20:29:08] havenwood: twopoint71: There are two Hashes in play. You have `magic` and you have `magic.default`.
[20:29:16] havenwood: twopoint71: Take a look at: magic.default
[20:31:43] havenwood: twopoint71: The 'watch' and 'out' keys are just used in your example to get access to the default. Note, they don't assign anything. They just pull up the default Hash value which is then mutated.
[20:32:01] havenwood: magic.default #=> {"closely"=>"this is the trick"}
[20:32:37] havenwood: Without the trickery: magic.default['closely'] #=> "this is the trick"
[20:34:00] havenwood: twopoint71: if you set the default proc instead, you'll get a fresh Hash for every new default:
[20:34:05] havenwood: not_magic = Hash.new { |h, k| h[k] = {} }
[20:35:08] havenwood: twopoint71: Yeah, they're just used to get access to #default.
[20:35:16] havenwood: twopoint71: magic['anything'] == magic.default
[20:35:44] havenwood: twopoint71: the same object_id even, the same object
[20:36:16] havenwood: &>> magic = Hash.new({}); magic.default.equal? magic[Object.new]
[20:36:47] havenwood: twopoint71: Any key you check that you haven't set is going to return that identical default Hash.
[20:38:06] havenwood: If you don't assign the key to a value, it's a noop for the `magic` Hash. But... you then assign a key to magic#default, which is what you're seeing here.
[20:38:13] havenwood: twopoint71: Does that make sense?
[20:39:25] havenwood: twopoint71: It does exist, because you assigned a default on this line: magic = Hash.new({})
[20:40:14] havenwood: it's just literally that same ({}) Hash object every time you look at the value of an unset key.
[20:41:08] havenwood: by using this idiom, you get a fresh Hash as the value for an unset key: Hash.new { |h, k| h[k] = {} }
[20:41:18] havenwood: so your trick wouldn't work
[20:41:29] havenwood: a Hash doesn't make a good default value for a Hash
[20:42:04] havenwood: but a proc that returns a Hash makes a fine default proc for a Hash

2019-01-16

[04:48:33] havenwood: baweaver: +1
[23:05:26] havenwood: devil_tux: I don't like the idea of mutation in a predicate method.
[23:10:44] havenwood: devil_tux: Folk might be able to provide better suggestions if you can zoom out and show a bit more context around where that code s being used.
[23:18:33] havenwood: &>> class Symbol; def << other; to_proc << other.to_proc end end; [1, 2, 3].map &:abs2 << :abs2
[23:25:58] havenwood: al2o3-cr: maybe also randomly frozen and tainted
[23:26:18] havenwood: and exlcude_end for good measure
[23:26:51] havenwood: al2o3-cr: :)

2019-01-15

[00:13:42] havenwood: phaul: Lots of work in SF!
[00:14:33] havenwood: phaul: Tried GitHub and GitLab?
[00:15:17] havenwood: The London folk I was thinking of are hiring in SF not London ¯\_(ツ)_/¯
[00:15:42] havenwood: London salaries are a good bit lower on average than NY or LA, iir
[00:18:38] havenwood: kyrylo (Pry dev) works at AirBrake. They're hiring remote frontend: http://jobs.airbrake.io/o/javascript-engineer-angular
[03:03:51] havenwood: Int, ah - they left. Was going to say ILIKE is Posgres for insensitive like: SELECT * FROM schools WHERE name ILIKE 'XX%'
[03:09:59] havenwood: Or even use a case insensitive type, citext.
[03:10:36] havenwood: https://www.postgresql.org/docs/current/citext.html
[03:43:25] havenwood: tpanarch1st: What are you making?
[03:44:52] havenwood: tpanarch1st: Ruby ships with support for a very simple DB called DBM.
[03:49:24] havenwood: tpanarch1st: You can use the mysql2 gem directly or use it from the Sequel gem.
[03:49:49] havenwood: tpanarch1st: Have you created a simple Rack app? Or a Roda or Sinatra app?
[03:50:35] havenwood: tpanarch1st: We call snippets of Ruby code we package and share "Gems."
[03:53:04] havenwood: tpanarch1st: https://github.com/brianmario/mysql2#usage
[03:55:07] havenwood: tpanarch1st: mysql2 is a gem. You can install it with: gem install mysql2
[03:55:19] havenwood: tpanarch1st: then from Ruby you can use it: require 'mysql2'
[03:55:49] havenwood: tpanarch1st: Gems are just snippets of Ruby code that people are sharing in formalized packages.
[03:56:36] havenwood: tpanarch1st: It's like downloading some code and evaling that code from the Ruby interpreter. It's not like apache modules, per se.
[03:57:41] havenwood: tpanarch1st: You're not loading the code for all Ruby programs. Just yours.
[03:59:00] havenwood: tpanarch1st: Start with in-memory.
[03:59:27] havenwood: tpanarch1st: Not saving anything to disk - just model it in Ruby.
[04:00:58] havenwood: tpanarch1st: I'm not familiar with giraffe. Show your code? We could probably help.
[04:01:26] havenwood: tpanarch1st: Do you have Ruby installed?
[04:01:40] havenwood: Start with installing Ruby.
[04:02:12] havenwood: tpanarch1st: From the command line, type: ruby -v
[04:03:29] havenwood: tpanarch1st: So you have Ruby 2.3. It's a bit dated, but it'll do.
[04:03:37] havenwood: tpanarch1st: Now type: irb
[04:03:57] havenwood: ?irb tpanarch1st
[04:04:35] havenwood: tpanarch1st: Try: 42 * 42
[04:04:36] havenwood: tpanarch1st: Or: print "Hello world"
[04:05:10] havenwood: tpanarch1st: So how would you represent a list of things?
[04:06:16] havenwood: tpanarch1st: Great, yes, in Ruby the Array literal is square braces. This is an empty Array: []
[04:06:35] havenwood: tpanarch1st: In irb, ask it if it's empty: [].empty?
[04:06:43] havenwood: &>> [1, 2, 3].empty?
[04:06:52] havenwood: tpanarch1st: Are you familiar with Hashes?
[04:07:28] havenwood: {"key" => "value", "another key" => "another value"}
[04:10:36] havenwood: tpanarch1st: Here's a little Rack webserver for you: https://gist.github.com/havenwood/f2374f754c1f02a8f9e8c09f5726011e
[04:10:47] havenwood: tpanarch1st: Save that as config.ru and you can run it with: rackup
[04:13:05] havenwood: tpanarch1st: In Rack, you respond to requests with three parts, 1) the status code, 2) a Hash of the HTTP headers, and 3) the body.
[04:13:21] havenwood: tpanarch1st: The 200 is just the status code for "OK"
[04:13:41] havenwood: tpanarch1st: These are the headers: {'Content-Type' => 'text/plain'}
[04:14:12] havenwood: tpanarch1st: Yes, it's an HTTP status code. 200 OK
[04:14:45] havenwood: tpanarch1st: Rack is a gem.
[04:15:15] havenwood: tpanarch1st: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
[04:16:58] havenwood: tpanarch1st: When you a web request with your browser or an API, you're just opening a socket and sending some text over it. It's a spec.
[04:19:00] havenwood: tpanarch1st: You can respond to a request with any code you'd like. In the Rack spec, this first thing is that response code.
[04:20:36] havenwood: tpanarch1st: In Ruby most webservers (Rails included) use Rack under the hood. You can make a simple Rack app directly to start groking what's going on.
[04:20:46] havenwood: tpanarch1st: It's a spec for handling HTTP 1.1 requests and responses.
[04:21:22] havenwood: tpanarch1st: https://rack.github.io/
[04:21:52] havenwood: tpanarch1st: It takes web requests, gives you an `env` Hash with info about the request and then you give it the response.
[04:22:43] havenwood: tpanarch1st: Yes, so that little snippet I wrote is one way to do that ^
[04:24:02] havenwood: tpanarch1st: a) an app is an application, which in the sense of web application is a little server that responds to HTTP requests with HTTP responnses
[04:24:37] havenwood: tpanarch1st: yes
[04:25:32] havenwood: tpanarch1st: b) a call method is a method named #call.
[04:26:36] havenwood: tpanarch1st: You can write an HTTP request by hand and type it out over socket. We don't though, since that's tedious. We use http clients.
[04:27:15] havenwood: tpanarch1st: Likewise, you can parse each HTTP request yourself when you receive it, but handling those connections and doing the parsing is tedious and complicated.
[04:27:43] havenwood: tpanarch1st: Rack ties together a pluggable webserver and a spec for easily creating web apps that respond to HTTP requests with HTTP responses.
[07:57:38] havenwood: Like HashWithIndifferentAccess? You'll love RangeWithIndeterminateExclusion! https://gist.github.com/havenwood/bdc8b23f8ec374ec3e0c9a330ee30938
[20:50:40] havenwood: baweaver: Yes! apeiros said in 2020 he'd actually consider it, and that's not far away now!
[22:03:01] havenwood: mr_rich101: res.uri.to_s
[22:03:05] havenwood: oops, wrong mr

2019-01-14

[00:34:36] havenwood: catbusters: Rails dropped the jQuery dep in 5.1.
[17:48:12] havenwood: za1b1tsu: Compare with: /\w*/
[23:15:28] havenwood: ModusPwnens: Consider using an ArgumentError and interpolating: raise ArgumentError, "expected odd number but `#{num}' is even" if num.even?
[23:17:18] havenwood: Nirvash: you can chain methods of ^
[23:19:18] havenwood: ModusPwnens: Interpolation saves a String allocation, spares an explicit #to_s call, and avoids needing parens.
[23:21:50] havenwood: ModusPwnens: gotcha - yeah the nested rescues remind me of a Ruby obfuscation submission: https://github.com/tric/trick2018/blob/master/01-kinaba/entry.rb
[23:22:15] havenwood: no-op program ^
[23:22:47] havenwood: 1st (Gold): "Most reserved" -- kinaba
[23:23:42] havenwood: I guess it's transcendental imbroglio, not obfuscation ¯\_(ツ)_/¯
[23:24:06] havenwood: I love mame's animation one: https://github.com/tric/trick2018/blob/master/02-mame/entry.rb
[23:41:29] havenwood: nfk: The Sequel gem is lovely

2019-01-13

[00:52:31] havenwood: al2o3-cr: In 2. 7!: chars.any? &/\s/.:match?
[00:52:57] havenwood: al2o3-cr: I guess you can already: any? /\s/
[00:53:17] havenwood: so not the best example for .: shining
[00:53:37] havenwood: &>> "foo\v\tbar\n baz".chars.any?(/\s/)
[05:28:50] havenwood: It's required by RubyGems, so although it's stdlib, it'll be available unless you disable gems.
[05:28:51] havenwood: ruby --disable-gems -e "p require 'uri'" #=> true
[05:28:58] havenwood: ruby -e "p require 'uri'" #=> false
[05:53:28] havenwood: sarink: It's nice to make sure your migrations' down works so you can: rails db:rollback
[05:54:07] havenwood: sarink: You want one migration to rollback another?
[05:56:10] havenwood: sarink: And it's not a reversible migration?
[06:06:59] havenwood: sarink: https://guides.rubyonrails.org/active_record_migrations.html#reverting-previous-migrations
[06:07:30] havenwood: sarink: Better to use #revert, I think.
[06:07:54] havenwood: sarink: you're welcome!
[06:08:58] havenwood: sarink: Best to use ^, but just for general reference, you can: ENV['VERSION'] = '1234'; Rake::Task['db:migrate:down'].invoke
[06:09:49] havenwood: sarink: Logs: http://logs.ryanbigg.com/RubyOnRails
[16:09:06] havenwood: roelof: Yes, VSCode should be a good text editor. Or take a look at Atom.
[16:10:15] havenwood: PCiobanita: Say what your issue is and someone who can help might!
[16:10:31] havenwood: PCiobanita: If it's not Rails, you might try the #ruby channel.
[16:10:50] havenwood: roelof: https://ruby.github.io/TryRuby/
[16:17:25] havenwood: PCiobanita: What issue are you running into?

2019-01-11

[01:19:09] havenwood: horribleprogram: I thought from what you first said that you might be using Groovy on Grails. Try Ruby on Rails!
[01:21:11] havenwood: Or TruffleRuby runs on GraalVM, and is quite impressive. (Graal isn't so far from Grails, after all.)
[01:24:47] havenwood: horribleprogram: But only one in a row.
[01:25:16] havenwood: &>> "#{1_0_0}%"
[01:26:13] havenwood: !troll horribleprogram
[01:26:37] havenwood: +b *!~horriblep@unaffiliated/nightcoder
[01:26:44] havenwood: +b horribleprogram!*@*

2019-01-10

[16:05:36] havenwood: I was going to say what baweaver said ^ too.
[16:06:07] havenwood: That extra Array is worth the allocation for expressiveness. Or use TruffleRuby so it folds away. ;P
[16:10:08] havenwood: mspo: Another way you'll commonly see it with %w is with braces: %w[200 201]
[16:10:17] havenwood: &>> %w[200 201]
[16:10:57] havenwood: mspo: An advantage is node calling #code twice.

2019-01-09

[16:26:36] havenwood: kidPalooma: 1. require 'base64'; Base64.strict_encode64 attachment_here
[16:32:22] havenwood: kidPalooma: You'll need a String to convert to Base64. You'll probably need #url_for that Variant to resolve it to a String.
[16:33:10] havenwood: dviola: Are all keys either `:comma` or `:dollar`?
[17:43:29] havenwood: dviola: I agree with the extract method refactoring. You might consider Regexp with named captures. Something like: https://dpaste.de/7BDT
[17:45:22] havenwood: dviola: I think it'd be nicer to assign @result to the return value of #flat_map and #map rather than shoveling.

2019-01-08

[01:30:50] havenwood: Quit: ZNC 1.7.1 - https://znc.in
[01:31:07] havenwood: has joined #RubyonRails-offtopic
[01:31:07] havenwood: Changing host
[01:31:07] havenwood: has joined #RubyonRails-offtopic
[01:31:21] havenwood: has joined #ruby-offtopic
[01:31:21] havenwood: has joined #ruby
[01:31:21] havenwood: has joined #RubyOnRails
[18:30:03] havenwood: za1b1tsu: What canton7 said. Gems in the gemspec are deps, and are installed alongside a gem. A Gemfile in a gem is for contributors to the gem, and often just has a `gemspec` directive - meaning install the gems in the gemspec. With gems, unlike apps, you don't commit the Gemfile.lock.
[18:30:56] havenwood: za1b1tsu: https://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/

2019-01-07

[18:55:14] havenwood: Caerus: https://gist.github.com/havenwood/5692bc5667d419b1bbf31d92663c4bb6
[18:55:25] havenwood: oops, bad autocomplete >.>
[18:55:29] havenwood: catbusters: ^
[18:57:17] havenwood: catbusters: If you aren't instantiating it, use a module instead of a class.
[19:04:33] havenwood: catbusters: They're different things.
[19:04:45] havenwood: catbusters: https://gist.github.com/havenwood/2d4cd1ac0cdcbfd61d77bda0ad81a373
[19:54:03] havenwood: phaul: Ah, gotcha. You're right, I misunderstood the question.
[21:03:06] havenwood: NeXTSUN: Nobody is going to give you guarantees.
[21:03:07] havenwood: NeXTSUN: https://ryanbigg.com/2015/06/mac-os-x-ruby-ruby-install-chruby-and-you
[21:04:48] havenwood: NeXTSUN: Are you already using Homebrew?
[21:07:25] havenwood: NeXTSUN: That ^ tutorial for setting up chruby should serve you well. It allows you to have multiple Rubies, as you might need for the varying version expectation across many projects.
[21:08:15] havenwood: NeXTSUN: You can also point chruby at the Homebrew Ruby. That's a quick way to get started if Ruby 2.6 is your cup of tea.
[21:10:08] havenwood: NeXTSUN: https://gist.github.com/havenwood/ba31f67c1d89ac236400
[21:21:10] havenwood: NeXTSUN: https://ryanbigg.com/2015/06/mac-os-x-ruby-ruby-install-chruby-and-you

2019-01-06

[20:00:38] havenwood: faraazahmad: Documentation improvements is one nice thing that's more accessible.
[20:01:12] havenwood: faraazahmad: If Ruby is your strong suit, consider contributing to an implementation that is written in a much higher percent Ruby - like TruffleRuby.
[20:02:16] havenwood: 46.4% Ruby! https://github.com/oracle/truffleruby
[20:03:29] havenwood: faraazahmad: https://github.com/oracle/truffleruby/blob/master/doc/contributor/workflow.md
[20:07:18] havenwood: faraazahmad: For example, you could implement Array#append and Array#prepend from Ruby 2.5. You can see those failing specs with:
[20:07:19] havenwood: PRETEND_RUBY_VERSION=2.5.0 jt test spec/ruby/core/integer/digits_spec.rb
[20:07:29] havenwood: PRETEND_RUBY_VERSION=2.5.0 jt test spec/ruby/core/array
[20:08:31] havenwood: Actually, that one looks fun. I'm going to do it right now. Feel free to join me!
[20:09:00] havenwood: There are lots to do. Many new features in 2.5 and 2.6. :)
[20:10:24] havenwood: faraazahmad: There're also some doable RubyGems issues in Ruby. Or lots of Gems to contribute to, of course.
[20:11:07] havenwood: faraazahmad: Of if you're in a shell mood, I have lots of chruby, ruby-install and RVM issues to triage if you want to pair on one of those.

2019-01-05

[21:16:05] havenwood: hays: The response is three things, the response code, headers and body:
[21:16:07] havenwood: [200, {'Content-Type' => 'text/plain'}, ['Hello hays']]
[21:17:06] havenwood: hays: To start doing routing, you need to look at env:
[21:17:15] havenwood: run -> env { if env[...
[21:17:35] havenwood: hays: https://rack.github.io/
[21:18:11] havenwood: hays: Roda, Hanami, Rails, Sinatra etc are all frameworks built as Rack adapters. They just provide Rack these three things as well.
[21:18:45] havenwood: hays: .ru is rack up
[21:18:54] havenwood: config dot rackup
[21:19:16] havenwood: hays: it is Ruby
[21:20:16] havenwood: hays: https://github.com/rack/rack/blob/master/bin/rackup
[21:21:09] havenwood: hays: Yes, it's quite helpful - and Rack and Rack middleware are still there when you have a framework on top - so still very useful to understannd.