I got an error installing the libv8 gem on Catalina:
$ gem install libv8 -v '3.16.14.19'
Building native extensions. This could take a while...
ERROR: Error installing libv8:
ERROR: Failed to build gem native extension.
current directory: /Users/will/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/libv8-3.16.14.19/ext/libv8
/Users/will/.rbenv/versions/2.4.5/bin/ruby -r ./siteconf20200217-34155-18bho1v.rb extconf.rb
creating Makefile
Applying /Users/will/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/libv8-3.16.14.19/patches/disable-building-tests.patch
Applying /Users/will/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/libv8-3.16.14.19/patches/disable-werror-on-osx.patch
Applying /Users/will/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/libv8-3.16.14.19/patches/disable-xcode-debugging.patch
Applying /Users/will/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/libv8-3.16.14.19/patches/do-not-imply-vfp3-and-armv7.patch
Applying /Users/will/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/libv8-3.16.14.19/patches/do-not-use-MAP_NORESERVE-on-freebsd.patch
Applying /Users/will/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/libv8-3.16.14.19/patches/do-not-use-vfp2.patch
Applying /Users/will/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/libv8-3.16.14.19/patches/fPIC-for-static.patch
Compiling v8 for x64
Using python 2.7.16
Using compiler: c++ (clang version 11.0.0)
Unable to find a compiler officially supported by v8.
It is recommended to use GCC v4.4 or higher
Beginning compilation. This will take some time.
Building v8 with env CXX=c++ LINK=c++ /usr/bin/make x64.release ARFLAGS.target=crs werror=no
GYP_GENERATORS=make \
build/gyp/gyp --generator-output="out" build/all.gyp \
-Ibuild/standalone.gypi --depth=. \
-Dv8_target_arch=x64 \
-S.x64 -Dv8_enable_backtrace=1 -Dv8_can_use_vfp2_instructions=true -Darm_fpu=vfpv2 -Dv8_can_use_vfp3_instructions=true -Darm_fpu=vfpv3 -Dwerror=''
CXX(target) /Users/will/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/libv8-3.16.14.19/vendor/v8/out/x64.release/obj.target/preparser_lib/src/allocation.o
warning: include path for stdlibc++ headers not found; pass '-stdlib=libc++' on the command line to use the libc++ standard library instead [-Wstdlibcxx-not-found]
In file included from ../src/allocation.cc:33:
../src/utils.h:33:10: fatal error: 'climits' file not found
#include
^~~~~~~~~
1 warning and 1 error generated.
make[1]: *** [/Users/will/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/libv8-3.16.14.19/vendor/v8/out/x64.release/obj.target/preparser_lib/src/allocation.o] Error 1
make: *** [x64.release] Error 2
/Users/will/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/libv8-3.16.14.19/ext/libv8/location.rb:36:in `block in verify_installation!': libv8 did not install properly, expected binary v8 archive '/Users/will/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/libv8-3.16.14.19/vendor/v8/out/x64.release/obj.target/tools/gyp/libv8_base.a'to exist, but it was not found (Libv8::Location::Vendor::ArchiveNotFound)
from /Users/will/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/libv8-3.16.14.19/ext/libv8/location.rb:35:in `each'
from /Users/will/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/libv8-3.16.14.19/ext/libv8/location.rb:35:in `verify_installation!'
from /Users/will/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/libv8-3.16.14.19/ext/libv8/location.rb:26:in `install!'
from extconf.rb:7:in `'
extconf failed, exit code 1
Gem files will remain installed in /Users/will/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/libv8-3.16.14.19 for inspection.
Results logged to /Users/will/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/extensions/x86_64-darwin-19/2.4.0/libv8-3.16.14.19/gem_make.out
The Solution
The solution was as follows:
$ brew install v8@3.15
$ gem install libv8 -v '3.16.14.19' -- --with-system-v8
Building native extensions with: '--with-system-v8'
This could take a while...
Successfully installed libv8-3.16.14.19
1 gem installed
I hit this error installing the latest Ruby using rbenv:
$ rbenv install 2.6.3
ruby-build: use openssl from homebrew
Downloading ruby-2.6.3.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.3.tar.bz2
Installing ruby-2.6.3...
ruby-build: use readline from homebrew
BUILD FAILED (OS X 10.14.4 using ruby-build 20190423)
Inspect or clean up the working tree at /var/folders/r7/kjzbwmx533b20hcf1_s9kc9c0000gn/T/ruby-build.20190501131413.33977
Results logged to /var/folders/r7/kjzbwmx533b20hcf1_s9kc9c0000gn/T/ruby-build.20190501131413.33977.log
Last 10 log lines:
compiling error.c
compiling eval.c
compiling file.c
compiling gc.c
file.c:23:10: fatal error: 'CoreFoundation/CFString.h' file not found
#include
^~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
make: *** [file.o] Error 1
make: *** Waiting for unfinished jobs....
The problem is missing headers. To re-install just run this command:
open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg
Now, Ruby should install just fine:
$ rbenv install 2.6.3
ruby-build: use openssl from homebrew
Downloading ruby-2.6.3.tar.bz2…
-> https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.3.tar.bz2
Installing ruby-2.6.3…
ruby-build: use readline from homebrew
Installed ruby-2.6.3 to /Users/will/.rbenv/versions/2.6.3
This gem can be a PITA to install on a mac, this is what worked for me. If you get this error:
charlock_holmes -v '0.7.6' | |
Building native extensions. This could take a while… | |
ERROR: Error installing charlock_holmes: | |
ERROR: Failed to build gem native extension. | |
current directory: /Users/will/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/charlock_holmes-0.7.6/ext/charlock_holmes | |
/Users/will/.rbenv/versions/2.6.1/bin/ruby -I /Users/will/.rbenv/versions/2.6.1/lib/ruby/2.6.0 -r ./siteconf20190213-34122-e636v8.rb extconf.rb | |
checking for -licui18n… yes | |
checking for -licui18n… yes | |
checking for unicode/ucnv.h… no | |
*************************************************************************************** | |
*********** icu required (brew install icu4c or apt-get install libicu-dev) *********** | |
*************************************************************************************** | |
*** extconf.rb failed *** | |
Could not create Makefile due to some reason, probably lack of necessary | |
libraries and/or headers. Check the mkmf.log file for more details. You may | |
need configuration options. | |
Provided configuration options: | |
–with-opt-dir | |
–without-opt-dir | |
–with-opt-include | |
–without-opt-include=${opt-dir}/include | |
–with-opt-lib | |
–without-opt-lib=${opt-dir}/lib | |
–with-make-prog | |
–without-make-prog | |
–srcdir=. | |
–curdir | |
–ruby=/Users/will/.rbenv/versions/2.6.1/bin/$(RUBY_BASE_NAME) | |
–with-icu-dir | |
–without-icu-dir | |
–with-icu-include | |
–without-icu-include=${icu-dir}/include | |
–with-icu-lib | |
–without-icu-lib=${icu-dir}/lib | |
–with-icui18nlib | |
–without-icui18nlib | |
–with-icui18nlib | |
–without-icui18nlib | |
To see why this extension failed to compile, please check the mkmf.log which can be found here: | |
/Users/will/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/extensions/x86_64-darwin-18/2.6.0-static/charlock_holmes-0.7.6/mkmf.log | |
extconf failed, exit code 1 | |
Gem files will remain installed in /Users/will/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/charlock_holmes-0.7.6 for inspection. | |
Results logged to /Users/will/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/extensions/x86_64-darwin-18/2.6.0-static/charlock_holmes-0.7.6/gem_make.out |
First, make sure you have installed the required dependencies:
brew install xz icu4c
Now, install charlock_holmes:
gem install charlock_holmes -v=0.7.6 -- --with-opt-dir=/usr/local/opt --with-opt-include=/usr/local/opt/icu4c/include --with-opt-lib=/usr/local/opt/icu4c/lib --with-cxxflags=-std=c++11
Tabs are clearly the one true indentation style, but when you create a new Ruby on Rails project it uses spaces, which could lead to a mish-mash of tabs and spaces in your project, not good!
The solution? Convert them using this one simple trick from the root of the project:
for i in `find app -name *.rb`; do echo $i; cat $i | unexpand -t2 > $i.converted; mv $i.converted $i; done
Repeat as necessary for other directories (test, config etc.) and other file types (erb).
Recently I posted on Twitter that I’d returned my new Macbook Pro. Some people were interested in why, and what my experience was, so here is is.
Caveat: This is all my opinion. There are some people who like the new keyboard, USB-C, and the touch bar, but then there are people who like the music of the Beautiful South, so I wouldn’t draw too many conclusions from that.
Back in 2014 I bought a new Macbook Pro, I got the mid 2014 model maxed out with 16GB memory, the 1TB SSD and the processor upgrade. It’s the machine I do all my work on, and spend a lot of my leisure time using, so for me the upgrades are worth the extra cost.
It was a real upgrade from my (I think) 2010 Macbook Pro. Faster, lighter, more capable. I don’t think I had a single gripe about it at all, it was a great machine.
This machine has served me well for three years, but for a while now has been suffering from the screen delamination issue that affected Macbook Pro screens at the time, and the trackpad has stopped clicking reliably. Neither of these are major problems, I use external monitors, keyboard and mouse.
It’s been hard to find the time to take it into the Apple store however as having it out of action for any period of time would be pretty hard to live with.
I finally decided that what I would do would be to get a new Macbook Pro, restore from a backup so I could continue working while my 2014 model was being repaired. I would then hand down the older computer to someone in my family. Three years should be time enough to feel like I was getting an upgrade, right?
About three weeks ago I received my new Apple Macbook Pro. Including two adapters the whole lot cost me £3,317.
Before I start on my list of whinges about the new Macbook Pro, there are a few good points.
That’s pretty much all the positive stuff I can think of, so on to the issues!
The first surprise was that there is a shorter (I think) power cable in the box. Previous macs shipped with a power brick that had a Magsafe connector on one side, and a power cable going to the plug on the other:
Apparently £3,249 is too tight a budget to include a section of mains cable and a plug.
The new mac doesn’t have what Apple have dubbed the “extension lead” or as I prefer to think of it, the “long enough power lead”. I haven’t measured the old cable, or the new one, but the new one didn’t feel long enough. I get that a lot of people probably didn’t use the “extension”, but I did all the time, and in my experience more than half of the people I see also used it. There aren’t many chairs in my house that are an extension-less power cable distance from a plug socket leaving room to shift about, and no, all my furniture isn’t in the middle of the room.
This was honestly pretty surprising, so much so that I spent a couple of minutes wondering wether I was just being stupid and the extension cable was hidden in the box, but no, though I was still stupid there was no hidden “extension” lead. I cannibalised one from the 2014 power cable because the new cable wasn’t long enough to reach my machine on my laptop stand.
Apple sell this “extension” cable for £19. 19. UK pounds. Not some sort of Venezuelan bat pound or something that converts to £3.50 sterling. Nineteen. Fucking. Pounds.
Magsafe was brilliant. It’s saved my laptop on several occasions. It seems Apple have totally forgotten, or are hoping we forget, the reason why Magsafe was so revolutionary.
Yeah bitch, magnets, ooooh indeed. A week into using my new Macbook Pro I had an incident where Magsafe would have helped. I switched my sit/stand desk to standing mode, as I do several times a dayweekmonthyear. The power cable had got caught on something and I only realised there was a problem when my laptop stand started to bend. The USB-C power cable was under incredible tension and I had to lower my desk to free it. Magsafe would have just popped out. With this new machine if I’d not noticed I could have broken my USB-C port or power plug.
Yes, I can buy a third-party adaptor, but I shouldn’t have to. Maybe you missed the £3,317 figure earlier, or didn’t watch that video where Steve Jobs explained how much of a PITA it is to have your laptop yanked onto the floor.
One of the great things about having had a few macs over the years is that I’ve got a decent number of power cables. If I head to my living room I can pretty much guarantee there’s a power cable I can use. If I go and work in the garden I don’t have to unplug the power cable at my desk. I can keep a power supply in my bag all the time.
These are all Magsafe 2 power supplies. Apple doesn’t sell a magsafe to USB-C adaptor, so these power supplies are all basically useless to me. The magsafe power cable that comes out of my Apple lightning monitor? Can’t use it.
The dongle situation on the new Mac is pretty crap. Just to get the same functionality that was completely built-in to my 2014 Mac I had to buy three:
– USB-C to Lightning
– USB-C to regular USB
– USB-C to mini display port (third party)
Yes I know that’s not a 2014 MBP, but that 2017 photo is legit.
And that was just to get it all working as it was day to day before (and ignores the magsafe power cable coming from the monitor issue). If I want to plug an HDMI monitor in, or an SD card I need more adapters. To make matters worse, the USB-C to mini display port adaptor I had to buy from a third party because Apple doesn’t make one. Maybe the USB-C to Lightning one works for this, maybe it doesn’t, I don’t know. Nothing I read on the Apple site suggests it does.
I get that USB-C might be the future, but having to buy, carry, and juggle multiple adaptors is a crappy experience, and are SD cards really so anachronistic that they don’t deserve a port of their own?
The new keyboard is loud. The sort of loud that I’d feel self-conscious and a bit selfish using in an open plan office, coffee shop, or train. I don’t quite get how Apple thought that the noise of typing on the new keyboard was OK.
Typing on the 2017 Macbook Pro.
The keys are much bigger, closer together, and lower profile. Though I think could have got used to the keyboard, it was annoying. Lower profile and closer together meant that my fingers couldn’t “reset” their understanding of their position on the edges of the keys so well. This meant I made more mistakes and found it harder to type fast. I was put in mind of the feeling of typing on an iPad with it’s lack of tactile feedback. Put in mind of the feeling of typing on an iPad with a rubber mallet.
I much preferred the 2014 model. I’m not sure if the drive for thinner laptops is worth the decrease in comfort and the *THUD* *THUD* *THUD*.
The touch bar feels like a gimmick, and one that ultimately detracts from the usability of the machine.
Juicero will surely go bust when someone launches an “Uber for juice”
When looking at the screen it required a context switch to use. Instead of having a predictable set of buttons I now need to look away from the screen, look to see what functions are available on the touch bar and where, use them, then get back to what I was doing. Every operation that I made on the touch bar was slower and more interrupting than the same operation using either a static set of buttons, or the mouse.
The most annoying change though was the lack of physical escape key. I knew I rested my finger on the escape key a lot (no, I don’t use Vim as my primary editor) and was curious how it would fare. Ultimately it was annoying.
I’m pretty uninterested in this. I used it to unlock my laptop and 1Password, but it wasn’t really much faster than the keyboard, if at all. I didn’t use Apple pay (though I do on my phone). Fingerprint recognition on the iPhone feels like a step up, if this is an advancement then it doesn’t feel like a large one.
It doesn’t feel revolutionary in the way I think face recognition might do.
I know the laptop was faster than my 2014 model, but there really didn’t seem to be much in it. I’m not sure what I was hoping for here, but I guess what I discovered is that my 2014 laptop was fast enough.
The new model still had 16GB RAM and a 1TB SSD, so there was no change there.
If Apple had made a laptop with the same keyboard from 2014, the same set of ports, magsafe and no touch bar I would have kept it even though it really doesn’t feel that much different performance wise than my 2014 machine. If I was switching from a 2010 mac this would have been an upgrade, but I’m not.
Individually these issues I could probably have lived with and got used to. Just ponied up £19 for a stretch of mains cord, or taken the risk of not having magsafe, but taken together they were more than I was willing to put up with.
If you like touch bars and bad keyboards, already carry a separate bag for adapters for your computer, or have no chair in your house further than 50cm from a plug socket you’re going to love this machine. If you’re upgrading from a crappy Air from 2010 it’s going to be an amazing speed upgrade with some irritating dongle shenanigans, but for me it was just disappointing.
Don’t take my word for it though, go ahead and get some more opinions, some people really like the keyboard, some people like the touch bar. These niggles are just the things that irritate me personally. Perhaps try one out. Apple make it really easy to return a laptop you decided you didn’t want.
Some people asked me about this, so here are the details. You can return most stuff to Apple really easily, even if you’ve used it, for up to two weeks. They even pick it up via UPS. Just make sure you return it within the time limit.
If you want to give the 2017 Macbook Pro a go you can order one and as long as you’ve not yanked it onto the floor by the power cable and bent the lid then you can return it to Apple for a full refund.
Someone asked on Twitter how I made my pasta sauce, so here it is!
The base of my Pasta sauce is largely this recipe, except I mostly don’t add mozzarella:
At it’s simplest I can make the whole thing for one person in 19 minutes, so it’s great for lunch.
85g dried pasta per person (50g per child). You can use whatever you want, I prefer spaghetti.
1 punnet of good tomatoes, about 225/250g (small ones, eg. baby plum, sunstream etc.)
Small bunch of basil or parsely.
Salt & Pepper
1 clove of garlic
1 chilli, I don’t de-seed
Olive oil
To start, boil some water in a medium pan. Add a decent amount of salt. While the water is coming up to the boil prepare the other ingredients.
First, chop the tomatoes, you can leave the skins on. I chop mine in half, I prefer the texture. It is also quicker. Finely chop the garlic and chilli. Roughly chop the basil or parsley.
As soon as the water comes to the boil, add your pasta. Now heat some oil over a medium heat in a small frying pan. Add in the chilli and garlic. Make *really* sure not to burn the garlic. Before the garlic browns add in the tomatoes then a good pinch of salt. Stir around for a few seconds. Now add in some water. It’s really easy to add in too much, you want just enough to cover the base of the pan, any more and you’ll end up with soup. You can always add more if you need to.
Next, add the basil or parsley. Stir through. When the pasta is al dente drain it retaining some of the cooking water and add to the sauce, stir around. Add pasta water if needed. You should still be able to work out what each of the individual parts of your sauce are made of. If you can’t you cooked it too long and/or added too much water.
At this point you can stir in mozzarella, I mostly don’t.
Slap it on a plate, grate parmesan over it and eat it.
With practice I’ve got this down to 19 minutes for the simple version, you might be faster if you can boil water faster than me. Adding more stuff makes it slower obviously.
Only get good tomatoes. They have to taste of something, if they don’t taste of anything your sauce will be crap. If you can’t get good fresh ones (or they have a gazillion air miles on them) use a *good* tin. It’s not as good and doesn’t work as well with the parsley or mozzarella versions, but it’s better than the alternative.
This sauce is great by itself, but you can add to it as you want. Some black pitted olives from a jar are great. If I’ve got other veg lying around, or more than one person eating I will add that too, depending on the density of the vegetable and how finely it is chopped depends when I add it. Chop it finer to cook it quicker. A good addition to bulk it up is a sweet pointed pepper & celery soffritto. One pointed pepper and 2 celery sticks is about the right balance with one punnet of tomatoes. Fennel and black olive are great too. Just be careful not to overdo it. There’s enough sauce with just the tomatoes for one person, less is more when adding extra ingredients.
If you do add more veg, try to keep the tomatoes per person ratio the same IMO.
In the photo above I went a bit mad and added:
– sweet pointed pepper & celery soffritto
– 1 small bulb of fennel, thinly sliced.
– Bacon*
It was really a bit too much.
*Bacnon! Chop some aubergine into ~1cm cubes or strips, one handful should be enough, think proportional to the other ingredients. Put on some foil, sprinkle salt on, create a parcel (crimp the edges to keep the water in) and oven cook at ~180°C (?, experiment) until just soft. Aubergine is great for adding some a bulky umami flavour in-place of meat.
I think that’s it! Nail the basic sauce then experiment on top of that and you’ve got a handy and versatile base!
The pad lock that had seized shut on my back gate was proving hard to remove, the hardened steel U was not yielding to my hacksaw. I noticed some rivets underneath that turned out to be soft steel. 10 minutes of sawing and I was in.
Hardened steel U
Soft steel rivets on the bottom
After removing the rivets, hammering off the bottom plate
Bottom plate revealed, lock mechanism removed
Lock open!
Say you have a graph like this:
How do you find out if there is a path between any of the two nodes? By using a breadth-first search:
require 'rgl/implicit' | |
require 'rgl/traversal' | |
vertices = ["one", "two", "three"] | |
g = RGL::ImplicitGraph.new do |g| | |
g.vertex_iterator { |b| vertices.map{|v| b.call(v) } } | |
g.adjacent_iterator { |x, b| b.call( vertices[(vertices.index(x) – 1).abs] ) } | |
g.directed = true | |
end | |
t = g.bfs_search_tree_from("one") | |
puts t.has_vertex?("two") # true | |
puts t.has_vertex?("three") # false |