I can never remember how to get here so this is more for my memory than anything else :
https://developer.apple.com/downloads/index.action
I can never remember how to get here so this is more for my memory than anything else :
https://developer.apple.com/downloads/index.action
I’ve worked at large companies and startups and know dozens of people who’ve done the same. Everyone comes across those companies who, from all outside opinion, should be regarded as “Technology” companies but end up labeling themselves as something different.
The label is important because it highlights a company’s focus. A service company focuses on service. A media company focuses on media. A hospitality company, you guessed it, focuses on hospitality.
For technology enthusiasts, it’s important to work at a company who respects, invests in, and fosters a solid technology foundation and culture.
If you could replace all the technology in your company with a purchased, widely available solution, would you and would the company’s value change?
If the company would still be able to provide the same value at the same cost, you are not in a technology company.
If a substantial portion of your company’s value would immediately disappear, you have a technology company on your hands! Congratulations!
This is an important question to ask yourself because it allows you to recognize warning signs earlier and to make sure you are in a job that you can be happy with over the long term.
Recognizing a company’s identity allows leadership to recognize where it can compromise and where it can’t. If a company is conflicted on its identity then it suffers from the inside out with competing interests and lack of focus.
If you find that you are not in a technology company and want to be, you need to leave. You are not going to get what you need and you are fighting what is best for the company.
If you are in a technology company and you are reading this post, you probably have some concerns. Does your leadership recognize they are running a technology company? Do you have a technology leader that can make and execute necessary decisions? Is staffing engineering as important as every other department, or is it anemic and overworked? Is engineering the most respected department in the company, or is it labelled as “IT” and ignored?
If your shoulders drooped at any of these questions, you have some important decisions to make. The most beneficial thing you can do for yourself throughout your career is to distill your future into as few easily assessable scenarios as possible.
If you’re happy, keep doing what you’re doing only more so. Make sure you are learning things that can be transferred to other companies.
If you’re not happy, try to change the company so that it’s a place you want to work. If it works, then great! If it doesn’t, then you know you need to go. If you happen to get fired for your efforts then even better, the choice was made for you!
Figure out where you are, figure out where you want to go, and make sure you act when you see things aren’t working out for you.
This is not a review, because I don’t know what I’m reviewing yet. This is my experience so far.
I was one of the lucky bastards who was selected to participate in the Glass Explorer program and purchase Google Glass for the bargain price of $1500 + tax. I’m not that notable of a developer or personality so presume I was a random grab in the Google+ application procedure.
4 months later, I was notified that I was eligible to order Glass and schedule pickup.
I was given the option to schedule my appointment online and, living in San Diego, I opted to head to the LA office. I made the decision to pick up my Glass on the way to Idyllwild, CA with my tired, hot, and cranky family in the car. Note that the only similarity in direction that LA and Idyllwild share is “North” which, being in San Diego, could also be said about Portland, Boston, and Canada. Note to self: Venice Beach is not remotely “on the way” to Idyllwild.
There was a valet sign for Glass Explorers at the Google LA offices surrounded by smiling Google employees all wearing their Glass (“shale” being their color of choice, it seems). I may have been slightly delirious after driving in hot LA traffic for 4 hours, but the sight of a half dozen smiling nerds was a welcome one. At the start everyone was happy and excited and it was easy to buy in to that atmosphere and get prepared for something fun.
My family and I were escorted in by a couple of employees, given a quick tour, offered drinks and food (mimosa and cookies or “breakfast” as I call it at my house), and set in front of a chrome pixel at our station. I was given the opportunity to choose my Glass color even though I had already picked one during the purchase process. I had selected “shale” (grey) but ended up choosing “carbon” (black). The orange and blue colors are really nice shades and, were I a less self conscious person, I would have chosen orange.
My Glass guide moved me through the pairing process, registration, the standard array of commands, and asked questions as to how I wanted or thought I wanted to use Glass. It was pretty basic and I wanted to play more but had a family to tend to. My son was antsy and was finding google an increasingly entertaining facility to explore and I was afraid of him molesting the displays of obscenely expensive glasses.
You’ve already read the gist of what Glass is, how it works, and what it does. Hopefully I can give you something new.
Picture: “Good enough”
There is nothing wonderful about the screen projection, other than the feeling that you are living in the future with an LCD projected in front of your eyeball. It works, but is difficult to read in sunlight and when looking at anything bright. It is not too hard to focus on but extended viewing is not too satisfying, easy, or comfortable. This is not usually a big deal because the information presented in your timeline isn’t enough to make you strain, but this may become relevant now with the latest update and the ability to browse actual websites (and play html5 video. Yeah, for real, right in front of your eyeball).
My wish : That it was slightly larger and easier to focus. It always has a “ghosty” feel due to reflection or being partially out of focus.
Audio: “Neat, but poor to useless”
The “bone conduction” technology used to transmit sound seems gimmicky and barely useful in this form. The theory is that a small, hard plate vibrates behind your ear and transmits sound to your inner ear via bone. In a quiet room you can definitely make out the sound and get use out of the text to speech, but other people can hear it as well so “bone conduction” is not really as critical an aspect as it sounds. In any amount of noise the sound becomes difficult to impossible to hear because 1) it’s not very loud to begin with, and 2) there’s no earbud so you have to compete with all ambient noise as well. The only way I know there is something being said half the time is because the vibration tickles my ear.
Unfortunately this is a pretty big deal because it makes using Glass as a bluetooth mic/speaker for your phone nearly impossible. This is doubly important because the idea of Glass benefits when you have more and more reason to keep it on all the time. I understand the need for non-intrusive audio delivery but this technology just doesn’t work well in common usage.
My wish : At least provide an audio jack and earbud options for people who find this important. I would even prefer no audio unless an earbud is used, that is how useless “bone conduction” is ending up for me. This is worth a slightly larger profile or dealing with the burden of an additional part to fumble for.
Camera : Awesome, awesome, awesome. Much better than expected.
I was impressed with the camera right away. It doesn’t suffer from the “press-and-wait” of most cell phone cameras; the picture is taken immediately. This camera does a really good job at capturing the picture the way I want the memory to be stored. This is the killer app for me so far and it’s hard to stress how impactful it was upon first use. I have never been a big picture taker and don’t really like having to worry about camera quality or settings when I’m just trying to capture my memory.
As a father, the memory I have of my children is largely dependent on the angle at which I look down at them, the height at which they look up at me, and eye contact. I can get these memories from Glass.
My Wish : To be able to take a picture via a two finger press or swipe of the touchpad. The physical button takes fumbling to find and requires coordination to press, and saying “Ok, Glass. Take a picture” is neat but gets tired after the 10th time and gets worse once your toddlers start running around the house saying it.
Feel and fit : Pretty good
Glass is much lighter than I expected and fits my head well. The screen is placed just above my right eye and is mostly in focus. Having demoed Glass literally over one hundred times, I’ve seen it just simply not fit on some people’s heads. Nothing is configurable except for the nose pads and the angle of the screen. If your ear doesn’t fit in between the touchpad and the battery, you are out of luck. If you have glasses, you are out of luck. If you can’t focus on the screen, you are out of luck.
That said, it fits me and fits me well. After long periods my right ear will get sore having bore the weight of glass, but that happens with regular sun and eyeglasses too.
There is a slight squeak as the metal and plastic bend while walking. Ok, it’s not much, but it’s my blog and I can post shit like this.
My Wish : Not much, Google did a damn good job. It also looks pretty slick.
Voice Input : Awesome, cumbersome, and awkward
The good: It does work and works well most of the time, even in loud ambient noise.
The Bad: Sometimes it doesn’t pick up anything, and it will also always pick up other people’s voices. This gets fun when you have people who get a kick out of shouting “OK GLASS, TAKE A PICTURE” as soon as you touch your temple.
The Awkward: When you want to google something, your first thought is “Hey, brain, let’s google this thought!” It is not “Hey brain and mouth, within 200 milliseconds, let us construct and enunciate an appropriate voice command followed by a query that will get us what we are looking for.” This leads to initiating the command for search as your brain gets hit with the first impulse followed by “Um, I uh where is uh get directions to, no, map chicken waffles, wait, michael jackson.”
The Reality: This doesn’t scale. If there were a lot of people with voice activated devices in public it would be so effing annoying. It is also difficult to know just what to ask in order to trigger special handling. I can ask “show traffic near me” and it will show me a map with traffic, but something like “How long will it take me to get home” doesn’t hit. “Will I need an umbrella today?” gives me a nice rundown of the weather and chance of rain, but “What will the weather be like tomorrow?” gives me standard google results. I understand this is complicated, but it’s important.
My Wish : Mind control or more gesture control.
Battery Life : Acceptable
The first day the battery life was awful. There is a feature to activate Glass via tilting your head up and down which works great but also seems to suck the battery down. Turning that setting off improved the life and I have been able to get a reliable day out of Glass. Video recording and navigation drain the battery a lot, a 20 minute video takes 40% of the battery (at least).
My Wish : A removable battery, and move the charging port to the very back so that people could conceivably charge Glass discreetly with a cable running down their back (hey, I would do it). Offer a battery addon that completes the wrap around the head and attaches to the left side. Battery life is going to be important. If Glass is expected to be worn often then it is going to need to be reliable. I can see Glass being commonly used for video recording and that is not something that can be done without worry right now.
Glass is awesome, but a lot of that awesomeness is that it is new, special, rare, and unique. It requires substantial retraining to use a device like this instead of the phone you’ve already grown reliant on. To retrain yourself you need to use it all the time. To use it all the time you need a reason to use it all the time.
What’s that reason? We don’t know yet. I feel like a guinea pig trying to show Google how somebody relatively normal would use their new toy. Right now I’m using it for pictures, video, and navigation. Everything else is icing and an excuse to keep the device on, but it’s not my core usage yet and, if it disappeared, I wouldn’t notice.
One last thing, you have to get used to being pointed at or stared at every time you wear Glass. People commonly criticize or make fun of me or the device from within earshot either because they aren’t aware I can hear them from 4 feet away or they just don’t care. This has been a fun process of self-growth over the past few weeks but it still takes me considerable effort to actually wear them in public. I used to be very introverted and self conscious but have forcefully pushed myself out of that hole over the past few years. Even still, I need to stop and take a breath before stepping out of my car and mentally prepare for questions, criticism, stares, and curiosity. Yes, poor me.
Edit /boot/config.txt
Add a line anywhere :
display_rotate=X
Where
The unexamined code is not worth releasing – Socrates (probably)
I wrote plato because socrates was too long a name for a command line tool. I also wrote plato because I love metrics. I love stupid little numbers that mean arbitrary things and I love watching some of them go up and I love watching some of them go down.
Most of them are meaningless.
Or maybe they’re super meaningful.
Does it matter?
What really matters is questioning your work. Why do these numbers come up? Why do some numbers go down when you do foo and why do some go up when bar? Do you like your code more when the number is higher, or lower?
I see a lot of comments regarding the relative value of plato’s metrics, as if I thought of them, and that’s great but missing the point. The truth is, even if I did pull these metrics out of the air, if they are consistently generated based off open criteria then they are still useful as long as you find them to be meaningful. You can have opinions as to what is considered an operand vs an operator and what those mean to other calculations, but the relative validity of an individual metric in this scenario is irrelevant. The value is the baseline you come to and maintaining alignment with what you find important.
One of the common points of contention is the “Estimated Number of Bugs” which is a metric I love in part because it looks so intuitive to the untrained eye (read: management). It doesn’t mean that your silly little dropdown might not work in IE8 if the user logs on with a spotty 3g connection while riding a donkey in singapore. It means that, given the complexity of the work that has been provided, there is a potential likelihood of X errors in the implementation. You may have 0 actual bugs, you may have 1000. Don’t get hung up on it, just think about it a minute.
At the end of the day, the best code is what powers the tools that people use daily and find valuable in their lives. Some of the most useful tools have code that would knock a wildebeast dead (vi anyone?) but that’s not what history remembers.
Release quickly. Refactor always.
Mass, overdue updates for people following me due to random projects.
– The JavaScript-Particle-System was rewritten to use requirejs and an event system on loan from Backbone (also featured in the NodeKnockout 2012 winner Disasteroids)
– Moved the bulk of grunt-preprocess out and published npm module preprocess. Grunt 0.4.0 support is available on a branch.
– RCL is up to 0.3.4 with features and fixes from Chris Miller for better firefox handling, also includes a small slew of other fixes only in the client. Server got updates to be more useful as a grunt task.
– grunt-contrib-jasmine was brought up to date with the feature-frozen grunt 0.4.0
– grunt-contrib-uglify has been updated to use the new UglifyJS version which includes support for sourcemaps.
Deprecation notices
– grunt-jasmine-runner will be deprecated as soon as grunt 0.4.0 hits, in favor of grunt-contrib-jasmine.
– I’m hoping to deprecate grunt-strip soon in favor of grunt-groundskeeper if that ends up serving the same purposes better. Everyone using grunt-strip is encouraged to check out that project.
I’m sitting in an airport after two days at HTML5 Dev Conf with plenty of time to think about the conf sprinkled with the occasional double check of my boarding pass to make sure I’m at the right gate.
Overall, the conf was worth going to, but the quality of the talks flip flopped between frustratingly amateur to mind blowingly awesome.
Paul Irish talked (slides) about how to enhance your toolchain and churned out loads of tools or aspects of tools I didn’t know about. SASS support around the corner in Chrome’s DevTools? Persistent JS snippets? Even Command-O was new to me and that’s already available. I had walked into the keynote expecting to hear mostly about Yeoman, which I’ve already played a bit with, but when he started talking I quickly had an “Oh shit” moment and realized I needed to break out the laptop and take notes.
Chris Heilmann talked about the broken promises of HTML5 and how unproductive it is to be wowed at and emulate things that Flash developers have been doing for the past 8 years. It’s awesome, yes, but we’re still under water when it comes to functionality that others have already come to expect and that we need to be making great applications. What is going to get us further, faster is to start exploiting the web for what it is best at and make bigger swings with widely accessible and richly functional sites/applications. Firefox OS promises to bridge a gap when it comes to device functionality exposed to web tech, but they’re targeting markets that I’m not in. It makes sense and is probably a good future investment but I’d love to see some focus in the US.
Steve Souders gave a great talk on caching and harped on some of the basics that are really important to get right like setting max-age and other cache headers. He mentioned why relying on heuristic caching, or what browsers or other clients do when no cache behavior is explicitly set, is unreliable for such an important aspect of your site and business. A few of Souders’ other stats highlighted just how important cache is, being more important than a fatter pipe or even disabling JavaScript in your browser (or, extrapolating from that, stripping all JavaScript from your site).
James Pearce of Facebook, a smart guy without a doubt, gave his frustratingly negative perspective on mobile web applications to the wrong crowd. The focus was the experience Facebook had developing and supporting their mobile application, generally considered a very poor quality app until they moved native. I can absolutely respect frustrations with mobile development with web technology; there are so many unknowns, problems that don’t yet have standard solutions, and a lack of decent development tools to aid the process. I, personally, might not even recommend going web tech at all on mobile depending on the developers you have access to, but to use the Facebook app as an example of the failure of the entire platform is irresponsible and genuine misinformation. One of the glaring failures of Pearce’s talk is his quote that the installed application’s lists look “pixel for pixel” the same as m.facebook.com because the same html is served. That is not a web application. That is a wrapper around a website. Facebook’s developers made some poor decisions and it is being used, publicly, as a shining example of how immature the web platform is. It was counter-productive and inappropriate for the audience and conference he was at.
Fortunately, Steve Newcomb gave a talk later in the day that appeared to expose a tip of the iceberg on untapped potential of the web platform. The Famo.us project makes some very large promises about performance on mobile devices and the demos were what everyone was talking about for the rest of the day. There were live demos on iPads after the talk that seemed to support the claims but, as with anything not actually released, it’s hard to know exactly what is being done and whether or not this is a general solution that will help many or a specific implementation that won’t be widely applicable. Check out the demos at the Famo.us site.
I’d love to get a closer look at the internals, so if you happen to sign up for early release, please use http://famo.us/r/VMCB to group your and my requests in the same bucket, hopefully weighting all of our requests more heavily.
There were other great talks (like Shay Howe‘s talk “Tactical CSS“) but my plane is landing. Maybe next time.
I came across grunt a few months ago and was amazed at how little time I spent looking at my build process before it. JavaScript was already in control of my frontend, backend, mobile, system scripts, and now it’s the entire build process. It’s amazing.
I’ve got tasks set up that look as gorgeous as this
[cc lang=’js’]
registerTask(‘dev’, ‘lint server sass open:dev watch’);
registerTask(‘build’, ‘lint sass requirejs preprocess strip min’);
[/cc]
Here are 6 grunt tasks that I’ve published this month that, when combined with everything already out there, have accelerated my development a huge amount.
grunt-strip allows you to strip out console.logs from your JavaScript source files. It also supports configuring other nodes you might want to strip out (like other debug libraries).
[cc lang=”js”]
grunt.initConfig({
strip : {
main : {
src : ‘htdocs/js/main.js’,
dest : ‘build/js/main.js’
nodes : [‘rcl’, ‘console’]
}
}
});
[/cc]
grunt-preprocess allows you to exclude or include parts of JavaScript and HTML files via directives that optionally depend on environment configuration.
[cc lang=”js”]
grunt.initConfig({
preprocess : {
index : {
src : ‘htdocs/main.html’,
dest : ‘build/main.html’
}
}
});
[/cc]
[cc lang=”html”]
[/cc]
[cc lang=”js”]
// exclude
expensiveDebugCode();
// endexclude
[/cc]
grunt-open simply allows you to open urls or files via task configuration.
[cc lang=”js”]
grunt.initConfig({
open : {
dev : {
url : ‘http://127.0.0.1:8000/htdocs’
}
}
});
[/cc]
[cc lang=”js”]
grunt.registerTask(‘dev’, ‘lint server open:dev watch’);
[/cc]
RCL (Remote Client Logging) is a tool written with grunt that allows you to log from your JavaScript application remotely to a terminal or web client. Visit rcljs.com for full documentation.
grunt-jasmine-runner is an tool to automate the generation and running of a jasmine-based specrunner through phantomjs.
[cc lang=”js”]
grunt.initConfig({
jasmine : {
src : ‘src/**/*.js’,
specs : ‘spec/**/*.js’
}
});
[/cc]
grunt-require-dir allows you to automatically generate requirejs-compatible AMD modules out of a directory tree. This is useful for bucketing alike resources without resorting to an full precompilation step that might remove some of the benefit of AMD.
[cc lang=”js”]
grunt.initConfig({
‘require-dir’ : {
all : {
plugin : ‘tpl’,
src : ‘test/fixtures/texttree/**/*.tmpl’,
baseDir : ‘test/fixtures/texttree/’,
prefixDir : ‘customDir/’,
dest : ‘test/fixtures/texttree.js’
}
}
});
[/cc]
Generates output like
[cc lang=”js”]
define(function(require){
return {
‘A’ : {
‘one’ : require(“tpl!customDir/A/one.tmpl”),
‘two’ : require(“tpl!customDir/A/two.tmpl”)
},
‘bar’ : require(“tpl!customDir/bar.tmpl”),
‘foo’ : require(“tpl!customDir/foo.tmpl”)
};
});
[/cc]
All told, grunt has opened up massive possibilities for me with JavaScript development. There is nothing particularly revolutionary about it, it’s just a bunch of incredibly useful tools located in one glorious place. Having such an important step be written in JavaScript makes it trivial to recognize a need for a task, switch to writing and finishing that task, and get back to coding your app with no expensive context switch.
[UPDATE: I just got an email from someone saying they use tabs over spaces because visually aligning everything by repeatedly pressing the spacebar is too cumbersome. That is not what is meant by using spaces over tabs! Every IDE/editor supports replacing tab presses with a dynamic and variable number of spaces until you get to the appropriate indentation level. It would be insane if this misunderstanding turned out to be one of the cruxes of the issue.]
I never really understood the Tabs vs Spaces debate. When I first started programming I started using tabs but almost immediately realized they just weren’t suited for the job. They promise flexibility but, in practice, that flexibility is largely a lie and you tie other developers to your indentation style regardless. If you are tying developers in to a style, then why use tabs which can add unexpected confusion?
In the examples below, tab characters are colored a darker grey. Don’t get hung up on the coding style, the issues of alignment are what’s important and the code is terse for example’s sake.
This example shows an initial setup that uses a 4-width tab for nearly everything. It looks great and beautiful when you are set up for a 4-width tab, but try changing the tab width with the buttons below the example.
All the careful alignment goes to crap when you change the tab width. Yes, the fact that you can change the tab width is a great option to have, but if it requires you to reformat your code then it is not actually a real feature of using tabs, it’s the same situation in any scenario. Either manual or automatic reformatting all around.
Below is the same example as above, but optimized for a 2 character width tab. The exact same problem applies, but you can also see that it takes a different number of tabs to produce similar alignments.
The last entry on our tabstop tour is an example that only uses tabs for block level indentation, which some people use as a solution to the above problems. This still has its own issues when alignments occur across block level indentations (look at the last block) but also raises the simple question “why?” Block level indentation is the simplest thing for an IDE to take control over, and the actual act of block indentation is almost always hidden from the developer. It is also the easiest to reformat globally since the rules for that are relatively standard, configurable in most decent IDEs or, at the least, tolerable.
Even if this is the most tolerable solution, it introduces yet another wrench into enforcing style with other developers. Now you need to make sure a developer only uses tabs for block level indentation, and spaces for alignment purposes.
And here is the example that doesn’t include tabs at all, just spaces and a 2 tab indentation level. The benefit here is unmistakable intent.
There is no chance for confusion and what you see is what you get.
Contributors/teams do still need to set a common config as to the number of spaces for indentation, but that is better than assuming you don’t need to do that with tabs and getting conflicting code style regardless.
Personally, it really doesn’t matter to me as long as there is a standard. If you use tabs, then you still need to add the tab width you are coding with to coding guidelines. The reason I use spaces is because the environment is self-describing. If you see two spaces, you know the guideline is a two character indentation level. If you see a tab and effed up alignment, you need to experiment with a few configurations in order to find the style the original developers were coding towards.
(and yes, “flexible” or “smart” tabs sound awesome, but are impractical in mixed environments where IDE/editor support is so spotty)
if (someVar === otherVar) bar(); // If we're otherVar else if (isThing) otherFn(); // Do awesome stuff else quux(); // Do bad stuff!!
function bar() {
if (anotherVariable === 42) { // If it's the answer
anotherFunction();
}
}
}
if (someVar === otherVar) bar(); // If we're otherVar else if (isThing) otherFn(); // Do awesome stuff else quux(); // Do bad stuff!!
function bar() {
if (anotherVariable === 42) { // If it's the answer
anotherFunction();
}
}
}
if (someVar === otherVar) bar(); // If we're otherVar else if (isThing) otherFn(); // Do awesome stuff else quux(); // Do bad stuff!!
function bar() {
if (anotherVariable === 42) { // Across block levels
anotherFunction(); // it still breaks
}
}
}
if (someVar === otherVar) bar(); // If we're otherVar else if (isThing) otherFn(); // Do awesome stuff else quux(); // Do bad stuff!!
function bar() { if (anotherVariable === 42) { // If it's the answer anotherFunction(); } } }
function updateExample(example,numTabs) { $('#'+example+' pre').html(TabFormatter.format($('#'+example+'Example').html(),numTabs,' ',1,'','')); }
(function(){ $('.tabExample button').click(function(evt){ var target = $(evt.target); var exampleId = target.parent().attr('id'); updateExample(exampleId,target.html()); }); updateExample('fourSpaceTab',4); updateExample('twoSpaceTab',2); updateExample('blockIndentOnly',2); $('#twoSpaces').html($('#twoSpaceExample').html()); })()
I finally published the require-dir task to npm last night so you can now install it alongside your gruntfile with
npm install grunt-require-dir
This task automates the process of grouping files or modules into an AMD container compatible, at least, with requirejs. Essentially “require”-ing a whole directory. I find myself creating module namespaces to group like-content together and this automates that, previously manual, process.
It allows you to turn a directory tree like this
[cc]
|_ /fixtures
| |_ /texttree
| | |_ /A
| | | |_ one.tmpl
| | | |_ two.tmpl
| | |_ bar.tmpl
| | |_ foo.tmpl
[/cc]
into this
[cc lang=’javascript’]
define(function(require){
return {
‘A’ : {
‘one’ : require(“tpl!customDir/A/one.tmpl”),
‘two’ : require(“tpl!customDir/A/two.tmpl”)
},
‘bar’ : require(“tpl!customDir/bar.tmpl”),
‘foo’ : require(“tpl!customDir/foo.tmpl”)
};
});
[/cc]