Using Bumbler to Reduce Runtime Dependencies - The Lean Software Boutique
Tool to show you which gems are slow to load:
➜ git:(master) ✗ bundle exec bumbler
[################################################# ]
(49/65) travis-lint...
Slow requires:
110.21 render_anywhere
147.33 nokogiri
173.83 haml
179.62 sass-rails
205.04 delayed_job_active_record
286.76 rails
289.36 mail
291.98 capistrano
326.05 delayed_job
414.27 pry
852.13 salesforce_bulk_api
Caching best practices & max-age gotchas - JakeArchibald.com
Showing various caching patterns. Includes WhatsApp screenshots.
VCR: An OAuth-compatible request matcher
OAuth requires a set of params to be carried along requests, among which a nonce. Some libraries pass these along as headers, some as query parameters. All fine.
When you're using VCR, the latter case is an issue. By default, requests are matched on method and URI. However, no request URI will equal another when they include a nonce. You won't be able to match these requests with VCR.
Solution
Obviously you need to...
Running the Awesome window manager within MATE
Awesome is a very good tiling window manager that provides neat features like automatic layouting of windows, good multi-display support with per display workspaces and more. Since it is only a window manager, you will probably miss some of MATE's conveniences like the network manager, application menus, automatic updates etc.
Fortunately, you can run Awesome within MATE, by following these steps (tested on Ubuntu MATE 16.04):
Awesome + MATE
- Create the followi...
Top-level constants in BasicObject
If you want to access top-level constants inside a BasicObject class, you need to prefix them with ::
.
This will not work
class Foo < BasicObject
def bar
Hash.new
end
end
Foo.new.bar # => NameError: uninitialized constant Foo::Hash
You need to explicitly write ::Hash
.
The reason is that top-level constants are internally attached to Object
, so Hash
is not in the lookup chain inside a BasicObject
.
Postgres Index Types
When creating an index using
CREATE INDEX
, Postgres will create a B-Tree type index by default. The B-Tree type is great for general purpose indexes but there are special cases when other types provide better results.
Test e-mail dispatch in Cucumber
Spreewald has steps that let you test that e-mails have been sent, using arbitrary conditions in any combination.
The attached file is for legacy purposes only.
Reading and writing cookies in JavaScript
You can use JavaScript to get or set cookie values on the client.
Using the vanilla JavaScript API
In JavaScript, document.cookie
is an accessor to all cookies on the current site. It looks like a String, but its setter is actually more powerful.
When setting cookies this way, remember to set the path=/
option.
Reading cookies
A result may look like this:
hello=universe; foo=bar
This means that there are 2 cookies: "hello" with value "universe", and "foo" with value "bar...
An interactive Git shell
Git commands tend to come in groups. Avoid typing git over and over and over by running them in a dedicated git shell.
You might want to run git config --global help.autocorrect true
before using gitsh
. This will silently swallow a muscle-memory "git" prefix to your commands inside the git shell.
How to fix: HTML5 video not working in IE9
While IE9 does support HTML5 <video>
tags, it fails to work until you force HTML5 mode.
Here are two ways to do that.
Option 1: Doctype
Make sure your HTML document uses HTML5. It should start like this:
<!DOCTYPE html>
Option 2: Magic meta tag
If you can not set a doctype, you use the X-UA-Compatible
meta tag in your HTML <head>
.
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
Infinitely nested hashes in Javascript (Coffeescript)
The NestedHash
class allows you to read and write hashes of any depth. Examples:
hash = {}
NestedHash.write hash, 'a', 'b', 'c', 'value' # => { a: { b: { c: 'value' } } }
NestedHash.read hash, 'a', 'b', 'c' # => 'value'
NestedHash.read hash, 'a' # => { b: { c: 'value' } }
NestedHash.read hash, 'foo', 'bar' # => undefined
Inspired by victusfate.
Code
class @NestedHash
@read: (objekt, keys...) ->
if objekt and keys.length
@read objekt[keys[0]], keys[1...]...
...
MySQL / MariaDB: Show disk usage of tables and columns
You can find out about disk space usage of all tables within your database by running this:
SELECT table_name AS `Table`, round(((data_length + index_length) / 1024 / 1024), 2) `Size (MB)` FROM information_schema.TABLES WHERE table_schema = "$your_database";
Replace $your_database
here.
To find out the disk usage of a single column:
SELECT sum(char_length($your_column))/1024/1024 FROM $your_table
Result is in megabytes again.
Ever wanted man pages that actually help? Here you go
Enter any command into explainshell and it will explain it to you: split into separate commands (if present), with each option explained.
About
Hello,
This site contains 29761 parsed manpages from sections 1 and 8 found in Ubuntu's manpage repository. A lot of heuristics were used to extract the arguments of each program, and there are errors here and there, especially in manpages that have a non-standard layout.
It is written in Python and uses bashlex, a bit of NLTK (to find the interesting parts of the manpage), a little d3....
Git: Delete a branch (local or remote)
To delete a local branch
git branch -d the_local_branch
To remove a remote branch (if you know what you are doing!)
git push origin :the_remote_branch
or simply use the new syntax (v1.7.0)
git push origin --delete the_remote_branch
Note
If you get the error
error: unable to push to unqualified destination: the_remote_branch
The destination refspec neither matches an existing ref on the remote nor
begins with refs/, and we are unable to guess a prefix based on the source ref.
error: failed to push some ref...
Analyse short links
Sometimes you might want to check a short link for it's destination before clicking on it. Additional you get information about the redirects.
Use the magic + at the end of the short url!
Google:
https://goo.gl/TXe0Kx
=> https://goo.gl/TXe0Kx+
Since the original publication of this post, Google's URL shortening service goo.gl has been discontinued.
Bitly:
http://bit.ly/1VRwNVt => [http://bit.ly/1VRwNVt+](http:/...
Looping through iterators in Coffeescript
Some modern Javascript APIs return iterators instead of arrays.
In plain Javascript you can loop through an iterator using
for...of
:
var iterator = ...;
for (var value of iterator) {
console.log(value);
}
While there is a for...of
construct in Coffeescript, it iterates through property/value pairs and **...
Manually uploading files via AJAX
To upload a file via AJAX (e.g. from an <input type='file'>
) you need to wrap your params in a FormData
object.
You can initialize a FormData
using the contents of a form:
var form = document.querySelector('form.my-form') // Find the <form> element
var formData = new FormData(form); // Wrap form contents
Or you can construct it manually, param by param:
var fileInput = document.querySelector('form input[type=file]');
var attachment = fileInput.files[0];
var f...
Postgresql: trigram indexes for searching
When full text search is overkill and like queries do not deliver this might be an approach you could try...
Get compiled code of a view template in Rails 4.2
If you want to inspect the compiled code of your erb (or haml) templates, you can run the following code in your view or your controller:
template = lookup_context.find_template(action_name, lookup_context.prefixes)
template.handler.call(template.refresh(self))
The output will be something like
@output_buffer = output_buffer || ActionView::OutputBuffer.new;@output_buffer.safe_append='My template
'.freeze;@output_buffer.to_s
Stackprof - sampling call-stack profiler for ruby
Stackprof is a sampling call-stack profile for Ruby 2.1+.
Instead of tracking all method calls, it will simply collect the current stack trace of a running program at fixed intervals. Methods that appear on top of the stack trace most often, are the methods your program spends most of its time in.
The big advantage of this is that it is very fast. You can even enable it in production and collect real performance data. See the README on how to add it as a middleware. It will dump its data to the tmp
directory.
Sampling is by default base...
How to fix routing error when using concerns in Rails up to 3.2.22.1
tl;dr
-
Don't write
resources :people, :concerns => :trashable
-
Write
resources :people do concerns :trashable end
Why
Writing a controller spec I encountered this error:
Failure/Error: get :index
ActionController::RoutingError:
No route matches {:controller=>"people"}
caused by this route definition
resources :people, :concerns => :trashable
which renders strange routes:
trash_person PUT /people/:id/trash(.:format) people#check {:concerns=>:trashable}
...
Linux: How To Fix Failed to fetch http://dl.google.com/linux/chrome/deb/dists/stable/Release : chrome
Chrome has discontinued support for 32-Bit Linux builds and this might break your apt-get update
.
To fix this, you need to update your APT source. This command does that automagically for you:
sudo sed -i -e 's/deb http/deb [arch=amd64] http/' "/etc/apt/sources.list.d/google-chrome.list"
Note that if you are using a 32-bit Linux, you will no longer receive Chrome security updates and should switch to a different browser (maybe Chromium).
nginx: How to drop connections for a location
If you want to configure your nginx to drop connections to a specific location
, you can do so by responding with HTTP response code 444.
Status 444 is a non-standard response code that nginx will interpret as "drop connection".
Example:
server {
listen 127.0.0.1;
location /api/ {
return 444;
}
}
An example use case is reverse-proxying with nginx and simulating a route that drops connections.
Capybara: Find the innermost DOM element that contains a given string
Let's say you want to find the element with the text hello
in the following DOM tree:
<html>
<body>
<article>
<strong>hello</strong>
<strong>world</strong>
</article>
</body>
</html>
You might think of XPath's contain()
function:
page.find(:xpath, ".//*[contains(text(), 'hello')")
Unfortunately that returns a lot more elements than you expect:
[ <html>...<html>,
<body>...</body>,
<article>...</article>,
<strong>hello</strong> ]
What you need to do instead is to *find all...