-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.xml
1077 lines (787 loc) · 66.2 KB
/
index.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Darren Coxall</title>
<link>http://www.darrencoxall.com/</link>
<description>Recent content on Darren Coxall</description>
<generator>Hugo -- gohugo.io</generator>
<lastBuildDate>Mon, 05 Oct 2015 09:00:00 +0000</lastBuildDate>
<atom:link href="http://www.darrencoxall.com/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>Understanding Maven</title>
<link>http://www.darrencoxall.com/java/understanding-maven/</link>
<pubDate>Mon, 05 Oct 2015 09:00:00 +0000</pubDate>
<guid>http://www.darrencoxall.com/java/understanding-maven/</guid>
<description>
<p>With a recent change of jobs I am finding myself <em>re-learning</em> java. The last time I used the language was in University and much of that was far from professional quality with regards to unit testing and software architecture. So with that in mind I am spending some time brushing up on the necessities one of which is dependency management.</p>
<p>It&rsquo;s easy enough to open up one of the high quality IDEs that are well known in the community such as Eclipse or IntelliJ, and get a dependency managed project running in no time. My problem with this is I like to know exactly what is happening, what has my IDE generated? and how can I achieve the same without ay IDE? So let&rsquo;s take a dive into Maven&hellip;</p>
<h2 id="what-is-maven:7664521576a6e38bce406d23fa54df85">What is Maven</h2>
<p>Maven is one of the most popular dependency resolution and management tools in the Java community. What this means <em>(initially)</em> to me is that it&rsquo;s a good choice for maintaining a set of external dependencies and ensuring our application is using specific versions that are known to work.</p>
<p>Installing maven is simple so I won&rsquo;t discuss that here, but you can find the official documentation <a href="https://maven.apache.org/install.html">here</a>.</p>
<p>The key file is <code>pom.xml</code> (Project Object Model) which represents your project and dependencies in XML. Much like a <code>Gemfile</code> for Ruby or <code>package.json</code> for node. So looking at the <a href="https://maven.apache.org/pom.html">reference guide</a> I&rsquo;m going to create something very basic.</p>
<pre><code>&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
&lt;groupId&gt;com.darrencoxall&lt;/groupId&gt;
&lt;artifactId&gt;learning-maven&lt;/artifactId&gt;
&lt;version&gt;1.0&lt;/version&gt;
&lt;/project&gt;
</code></pre>
<p>Here we need to ignore the <code>modelVersion</code> as 4 is the only acceptable version. The proceeding 3 attributes define the information about my own particular project.</p>
<p>With that defined I decided to see what happens when I run <code>mvn clean install</code>&hellip; The answer is lots to my surprise. I haven&rsquo;t even declared any dependencies yet. The output looks as though it has downloaded some maven related plugins so let&rsquo;s have a look at what they are.</p>
<ul>
<li><code>maven-clean-plugin</code> removes build-time generated files</li>
<li><code>maven-resources-plugin</code> copies the relevant resource files to the output directory</li>
<li><code>maven-compiler-plugin</code> contains the compilation logic which is independent to the JDK used for maven</li>
<li><code>maven-surefire-plugin</code> generates a report of test results</li>
<li><code>maven-jar-plugin</code> which builds a JAR file</li>
</ul>
<p>So these plugins are providing some of the basics but presumably maven can do a lot more via plugins as the core feature set is built as plugins.</p>
<p>We also have a new directory called &ldquo;target&rdquo;. This is where our build artifacts are stored so this directory would presumably be ignored from any VCS.</p>
<h2 id="using-maven:7664521576a6e38bce406d23fa54df85">Using Maven</h2>
<p>I&rsquo;m now going to add a very simple application&hellip;</p>
<pre><code>// src/main/java/Application.java
package learningmaven;
class Application {
public static void main(String[] arguments) {
System.out.println(&quot;Hello, World!&quot;);
}
}
</code></pre>
<p>Again running <code>mvn clean install</code> results in a few more things in the target directory. I&rsquo;m not particularly bothered by them though as I should now have a working JAR file right?</p>
<pre><code>$ java -jar target/learning-maven-1.0.jar
no main manifest attribute, in target/learning-maven-1.0.jar
</code></pre>
<p>So no, how is main set then? Well a bit of searching and I discovered the maven-jar-plugin can be configured to generate the relevant meta files for the jar. So my <code>pom.xml</code> will now look like the following: <em>key points are the addClasspath and mainClass</em></p>
<pre><code>&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
&lt;groupId&gt;com.darrencoxall&lt;/groupId&gt;
&lt;artifactId&gt;learning-maven&lt;/artifactId&gt;
&lt;version&gt;1.0&lt;/version&gt;
&lt;build&gt;
&lt;plugins&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
&lt;artifactId&gt;maven-jar-plugin&lt;/artifactId&gt;
&lt;version&gt;2.4&lt;/version&gt;
&lt;configuration&gt;
&lt;archive&gt;
&lt;manifest&gt;
&lt;addClasspath&gt;true&lt;/addClasspath&gt;
&lt;mainClass&gt;learningmaven.Application&lt;/mainClass&gt;
&lt;/manifest&gt;
&lt;/archive&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;
&lt;/plugins&gt;
&lt;/build&gt;
&lt;/project&gt;
</code></pre>
<p>Now let&rsquo;s just try this again&hellip;</p>
<pre><code>$ mvn clean install
$ java -jar target/learning-maven-1.0.jar
Hello, World!
</code></pre>
<p>Success! We have configured maven to build our project without any IDE. So now I want to use some dependencies and see how that works.</p>
<h2 id="dependencies-in-maven:7664521576a6e38bce406d23fa54df85">Dependencies in Maven</h2>
<p>I&rsquo;m going to add <a href="http://www.joda.org/joda-time/">Joda-Time</a> to my project as it&rsquo;s a well respected time library.</p>
<p>To do this I need to add the following into my POM.</p>
<pre><code>&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;joda-time&lt;/groupId&gt;
&lt;artifactId&gt;joda-time&lt;/artifactId&gt;
&lt;version&gt;2.8.2&lt;/version&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
</code></pre>
<p>Fast-forward a bit and I also discovered that maven won&rsquo;t automatically make dependencies available to the classpath and so we need to automate this with another plugin, maven-dependency-plugin.</p>
<pre><code>&lt;plugin&gt;
&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
&lt;artifactId&gt;maven-dependency-plugin&lt;/artifactId&gt;
&lt;executions&gt;
&lt;execution&gt;
&lt;id&gt;copy-dependencies&lt;/id&gt;
&lt;phase&gt;package&lt;/phase&gt;
&lt;goals&gt;
&lt;goal&gt;copy-dependencies&lt;/goal&gt;
&lt;/goals&gt;
&lt;configuration&gt;
&lt;outputDirectory&gt;${project.build.directory}&lt;/outputDirectory&gt;
&lt;overWriteReleases&gt;false&lt;/overWriteReleases&gt;
&lt;overWriteSnapshots&gt;true&lt;/overWriteSnapshots&gt;
&lt;/configuration&gt;
&lt;/execution&gt;
&lt;/executions&gt;
&lt;/plugin&gt;
</code></pre>
<p>With this in place dependencies are then available to our code and packaged into our jar. So let&rsquo;s use joda-time in our code.</p>
<pre><code>package learningmaven;
import org.joda.time.Instant;
class Application {
public static void main(String[] arguments) {
Instant now = Instant.now();
System.out.println(now);
}
}
</code></pre>
<p>Finally we can compile and build the project and see if it works.</p>
<pre><code>$ mvn clean install
$ java -jar target/learning-maven-1.0.jar
2015-10-03T20:41:27.516Z
</code></pre>
<p>Fantastic. So in this we have learnt a bit about how we can use maven to manage dependencies as well as bundle them into our applications. It can do a hell of a lot more but understanding the basics is important, it means I have a better understanding of maven outside of the interfaces available within an IDE.</p>
<p>It&rsquo;s so easy to become reliant on IDEs to create and work with Java projects but I want to make sure that the use of the tools doesn&rsquo;t obscure my understanding of the technologies. I want to be able to create small java applications from my terminal.</p>
<p><em>Apologies if this is quite a simple task but being new/out-of-date to java means these simple subjects are often overlooked and shared learning is better than private learning.</em></p>
</description>
</item>
<item>
<title>Refactoring Walkthrough</title>
<link>http://www.darrencoxall.com/ruby/refactoring-walkthrough/</link>
<pubDate>Thu, 01 Jan 2015 10:00:00 +0000</pubDate>
<guid>http://www.darrencoxall.com/ruby/refactoring-walkthrough/</guid>
<description><p>Refactoring is the process of restructuring, re-architecting and modifying
existing code without affecting the output of the code. The aim is to reduce
complexity simultaneously improving the ability to modify the code at a later
date. I want to walk you through my own refactoring process with a real world
example.</p>
<p>We will be refactoring <a href="https://github.com/shtirlic/sinatra-jsonp">shtirlic/sinatra-jsonp</a>. This is a small
sinatra extension that adds support for older browsers when returning json as
it provides callback function support. I have selected this as I have used it in
a project and I know that the main bulk of the functionality is implemented in
a rather complex method making it a prime candidate for refactoring.</p>
<p>So to begin with I am going to fork the repository so my starting point is
<a href="https://github.com/dcoxall/sinatra-jsonp/tree/7436fd1fa38d6654560fa3e4af52c734dd818073"><code>7436fd1fa3</code></a>. If I now clone this locally I can start setting up my
baselines and checking the tests.</p>
<p><em>Tests are perhaps the single most important thing to have in place when
refactoring. Without them it is extremely difficult to assert that the code is
producing the same results both before and after the refactoring.</em></p>
<pre><code>$ git clone git@github.com:dcoxall/sinatra-jsonp.git
$ cd sinatra-jsonp
$ bundle install
$ bundle exec rake
</code></pre>
<p>You will see that I installed any dependencies and then ran the default rake
task. In most ruby programs this is the standard way of running the complete
test suite. In this case it was right and all the tests passed but there were
some deprecations.</p>
<blockquote>
<p>stdlib is deprecated. Use :test_unit or :minitest instead</p>
</blockquote>
<p>Now this is a good place to start. If I can fix any issues like this now I will
have a nicer environment to work with later so at this point I will create a
branch.</p>
<pre><code>$ git checkout -b refactor
</code></pre>
<p>With a branch created I can start making my changes. The offending line causing
the deprecation warning is in <code>spec/spec_helper.rb</code> so my first action was to
remove it and see what effect it had on the tests by running them again.</p>
<p>Low-and-behold everything passed but without any warnings. Awesome. So I can
commit this change.</p>
<pre><code>$ git add spec/spec_helper.rb
$ git ci -m &quot;Fix deprecated use of stdlib&quot;
</code></pre>
<p>Now I want to introduce a tool I like to use called <a href="https://github.com/bbatsov/rubocop">rubocop</a> which
can analyse ruby code to check that it follows particular conventions but more
importantly in this case it also includes metrics that report on estimated
complexity and an ABC rating (Assignments, branching and conditions) where a
higher number often indicates complex or difficult to follow code. This will
provide me a baseline and I can work on reducing these metrics providing me a
tangible target.</p>
<pre><code>$ gem install rubocop
$ rubocop -f s --only \
&gt; Metrics/AbcSize,Metrics/MethodLength,Metrics/PerceivedComplexity
</code></pre>
<p>In the above command I limit rubocop to look only for ABC rating, method length
and the perceived complexity. These will be the metrics I want to improve. The
result is the following:</p>
<pre><code>== lib/sinatra/jsonp.rb ==
C: 6: 5: Assignment Branch Condition size for jsonp is too high. [19.34/15]
C: 6: 5: Method has too many lines. [19/10]
C: 6: 5: Perceived complexity for jsonp is too high. [8/7]
</code></pre>
<p>Now I have a starting point and passing tests. It&rsquo;s time to look at the code.
All the reported issues are in <a href="https://github.com/dcoxall/sinatra-jsonp/blob/7436fd1fa38d6654560fa3e4af52c734dd818073/lib/sinatra/jsonp.rb"><code>lib/sinatra/jsonp.rb</code></a> which is where all
the main logic is kept.</p>
<p>My first instinct is to go through the method and document what it is actualy
doing. I find it much easier to re-structure the code once I understand what
functions it is serving. It is then a case of moving pieces to their own
methods.</p>
<pre><code>def jsonp(*args)
# requires 1 or more arguments
if args.size &gt; 0
# The first argument is the object to serialize
data = MultiJson.dump(
args[0],
:pretty =&gt; settings.respond_to?(:json_pretty) &amp;&amp; settings.json_pretty
)
# If we have another argument it is the callback function name
if args.size &gt; 1
callback = args[1].to_s
else
# If not then determine the callback based on the following parameters
['callback','jscallback','jsonp','jsoncallback'].each do |x|
callback = params.delete(x) unless callback
end
end
# If we have a callback perform some basic sanitization and set the
# response content type and the eventual response body
if callback
callback.tr!('^a-zA-Z0-9_$\.', '')
content_type :js
response = &quot;#{callback}(#{data})&quot;
else
# If no callback then set the response content type to json and return
# the serialized data
content_type :json
response = data
end
response
end
end
</code></pre>
<p>With this view I am going to work top-down and so first is to implement a guard
condition by returning early if we have in-sufficient arguments. I then decide
that I can make the <code>pretty</code> flag into a different method.</p>
<pre><code># requires 1 or more arguments
return if args.size &lt; 1
# The first argument is the object to serialize
data = MultiJson.dump(args[0], :pretty =&gt; display_pretty_json?)
# ...
private
def display_pretty_json?
!!(settings.respond_to?(:json_pretty) &amp;&amp; settings.json_pretty)
end
</code></pre>
<p>Now running the tests and rubocop again reveal that everything is still passing
but I have already corrected the perceived complexity of the method as well as
improved the ABC score (by 3.03).</p>
<pre><code>== lib/sinatra/jsonp.rb ==
C: 6: 5: Assignment Branch Condition size for jsonp is too high. [16.31/15]
C: 6: 5: Method has too many lines. [18/10]
</code></pre>
<p>Time to commit these changes and then tackle the callback calculation.</p>
<pre><code>$ git add lib/sinatra/jsonp.rb
$ git commit -m &quot;Introduce guard condition and extract setting checks&quot;
</code></pre>
<p>I move the logic for determining the callback name into a new method and I also
move the list of parameter keys to check into a constant. This leaves us with
the following&hellip;</p>
<pre><code>CALLBACK_PARAMS = %w( callback jscallback jsonp jsoncallback ).freeze
def jsonp(*args)
return if args.size &lt; 1
data = MultiJson.dump(args[0], :pretty =&gt; display_pretty_json?)
callback = extract_callback_name(args[1])
# If we have a callback perform some basic sanitization and set the
# response content type and the eventual response body
if callback
callback.tr!('^a-zA-Z0-9_$\.', '')
content_type :js
response = &quot;#{callback}(#{data})&quot;
else
# If no callback then set the response content type to json and return
# the serialized data
content_type :json
response = data
end
response
end
alias JSONP jsonp
private
def display_pretty_json?
!!(settings.respond_to?(:json_pretty) &amp;&amp; settings.json_pretty)
end
def extract_callback_name(name = nil)
if name.nil?
callback = nil
CALLBACK_PARAMS.each do |key|
callback = params.delete(key) unless callback
end
callback ? callback.to_s : nil
else
name.to_s
end
end
</code></pre>
<p>Again running the tests and rubocop tell me that everything is still working
and I have now also corrected the ABC score to an acceptable level. The only
metric that rubocop is complaining about now is the method length. Once again,
it&rsquo;s time to commit our changes and move onto finalizing the response.</p>
<pre><code>$ git add lib/sinatra/jsonp.rb
$ git commit -m &quot;Callback name extraction moved to new method&quot;
</code></pre>
<p>Now for this next refactor I don&rsquo;t want the method to have any side-effects and
so I don&rsquo;t want the new method to call <code>content_type</code> explicitly but instead
return both the response body and the correct content type which the main method
can use.</p>
<p>The result of this is shown below</p>
<pre><code>CALLBACK_PARAMS = %w( callback jscallback jsonp jsoncallback ).freeze
def jsonp(*args)
return if args.size &lt; 1
data = MultiJson.dump(args[0], :pretty =&gt; display_pretty_json?)
callback = extract_callback_name(args[1])
type, response = determine_response(data, callback)
content_type(type)
response
end
alias JSONP jsonp
private
def determine_response(data, callback = nil)
return [:json, data] if callback.nil?
callback.tr!('^a-zA-Z0-9_$\.', '')
[:js, format(&quot;%s(%s)&quot;, callback, data)]
end
def display_pretty_json?
!!(settings.respond_to?(:json_pretty) &amp;&amp; settings.json_pretty)
end
def extract_callback_name(name = nil)
if name.nil?
callback = nil
CALLBACK_PARAMS.each do |key|
callback = params.delete(key) unless callback
end
callback ? callback.to_s : nil
else
name.to_s
end
end
</code></pre>
<p>Running the tests and rubocop now reveal all tests continue to pass and rubocop
has nothing to complain about! I can commit this and create a pull request.</p>
<p>I&rsquo;ve demonstrated how I like to refactor with the aim of making the code easier
to work with. What once was a large single method is now several smaller more
succinct methods. This also provides an additional benefit in that the method
names now also document the behaviour of the code making it easier for others to
read and understand.</p>
<p>Thank you for reading. You can see the <a href="https://github.com/shtirlic/sinatra-jsonp/pull/6">final pull request here</a>. Now go out
and improve some code!</p>
</description>
</item>
<item>
<title>Executing Commands in Go</title>
<link>http://www.darrencoxall.com/golang/executing-commands-in-go/</link>
<pubDate>Mon, 18 Aug 2014 09:00:00 +0000</pubDate>
<guid>http://www.darrencoxall.com/golang/executing-commands-in-go/</guid>
<description>
<p>The ability to execute external commands from within an application is something I often feel is a bit <em>hackish</em> and I haven&rsquo;t yet discovered a language that handles it as well as I would like. That was until I learned to love how Go tackles the challenge. This post will show you how to make the most of <code>os/exec</code>.</p>
<p>I tend to feel that there are three different types of command execution within applications.</p>
<ul>
<li>Plain output. For when you always expect the command to execute but all you want from it is the output.</li>
<li>Exit codes. These perform some cleanup, setup or check and you want to discard any output but assert the exit code.</li>
<li>Long running processes. This case is rarer but there are times when I want to spawn sub-processes. Maybe even starting up another server to proxy to for instance.</li>
</ul>
<p>So how do I handle these in Go? The magic all comes from the wonderful <a href="http://godoc.org/os/exec" title="GoDoc: os/exec">os/exec</a> which is part of the Go standard library. Using this library, commands become a first class citizen within your application.</p>
<p><em>For all examples I am only going to include the primary logic but I will keep a link to a full copy in the Go Playgroud. The copies won&rsquo;t execute within the Playground due to the restrictions Google have in place but they should run fine locally.</em></p>
<p>I have defined the following functions to keep the examples short:</p>
<pre><code>func printCommand(cmd *exec.Cmd) {
fmt.Printf(&quot;==&gt; Executing: %s\n&quot;, strings.Join(cmd.Args, &quot; &quot;))
}
func printError(err error) {
if err != nil {
os.Stderr.WriteString(fmt.Sprintf(&quot;==&gt; Error: %s\n&quot;, err.Error()))
}
}
func printOutput(outs []byte) {
if len(outs) &gt; 0 {
fmt.Printf(&quot;==&gt; Output: %s\n&quot;, string(outs))
}
}
</code></pre>
<h2 id="collecting-output:b15a4def803f966fde627651ff8cb67a">Collecting output</h2>
<p>The first and most obvious use is to collect output from an external command. An easy way to do that is to use the <code>CombinedOutput</code> function.</p>
<pre><code>// Create an *exec.Cmd
cmd := exec.Command(&quot;echo&quot;, &quot;Called from Go!&quot;)
// Combine stdout and stderr
printCommand(cmd)
output, err := cmd.CombinedOutput()
printError(err)
printOutput(output) // =&gt; go version go1.3 darwin/amd64
// http://play.golang.org/p/-7PWDpt6zS
</code></pre>
<p>This works well if you also want to check for any error messages output but if you want finer control over the output of a command then we can route it into different buffers giving us control over both standard output and standard error.</p>
<pre><code>// Create an *exec.Cmd
cmd := exec.Command(&quot;go&quot;, &quot;version&quot;)
// Stdout buffer
cmdOutput := &amp;bytes.Buffer{}
// Attach buffer to command
cmd.Stdout = cmdOutput
// Execute command
printCommand(cmd)
err := cmd.Run() // will wait for command to return
printError(err)
// Only output the commands stdout
printOutput(cmdOutput.Bytes()) // =&gt; go version go1.3 darwin/amd64
// http://play.golang.org/p/_6xke11GMp
</code></pre>
<p>In the above example we manually connect our own buffer to capture the commands stdout stream. We can do the same for stderr and even stdin so long as it adheres to the <code>io.Reader</code> interface.</p>
<p>So far we&rsquo;ve seen how easy it is to capture command output across multiple file descriptors. It&rsquo;s more verbose then other languages but it gives us lots of flexibility.</p>
<h2 id="exit-codes:b15a4def803f966fde627651ff8cb67a">Exit codes</h2>
<p>Retrieving the exit code of a command is easy with Go. You may have already noticed in the previous examples that when executing the command Go can return an error. These errors occur if there is an issue with IO or of the command doesn&rsquo;t return a successful exit code (0).</p>
<p>The following code will output the exit code of a command.</p>
<pre><code>cmd := exec.Command(&quot;ls&quot;, &quot;/imaginary/directory&quot;)
var waitStatus syscall.WaitStatus
if err := cmd.Run(); err != nil {
printError(err)
// Did the command fail because of an unsuccessful exit code
if exitError, ok := err.(*exec.ExitError); ok {
waitStatus = exitError.Sys().(syscall.WaitStatus)
printOutput([]byte(fmt.Sprintf(&quot;%d&quot;, waitStatus.ExitStatus())))
}
} else {
// Command was successful
waitStatus = cmd.ProcessState.Sys().(syscall.WaitStatus)
printOutput([]byte(fmt.Sprintf(&quot;%d&quot;, waitStatus.ExitStatus())))
}
// http://play.golang.org/p/m2A17UWSOL
</code></pre>
<p>The above code looks more complicated but in traditional Go fashion it handles many situations.</p>
<ul>
<li>Create an <code>*exec.Cmd</code></li>
<li>Execute and test for any errors</li>
<li>If we received an error then check it was because of the commands exit</li>
<li>If no error then check the commands <code>*os.ProcessState</code> for the exit code (pretty much guaranteed to be 0 but in here for completion)</li>
</ul>
<p>A caveat to take note of is that if Go failed to locate the command in your <code>$PATH</code> then it won&rsquo;t ever execute the command and thus you will have no exit code. This is why it is important to assert the type of error returned.</p>
<h2 id="long-running-processes:b15a4def803f966fde627651ff8cb67a">Long running processes</h2>
<p>All our above examples are synchronous. They wait for the command to complete before continuing the execution of our application. If we wanted to execute a long running task however it is likely that we want it to happen asynchronously. Once again this is trivially easy.</p>
<pre><code>cmd := exec.Command(&quot;cat&quot;, &quot;/dev/random&quot;)
randomBytes := &amp;bytes.Buffer{}
cmd.Stdout = randomBytes
// Start command asynchronously
err := cmd.Start()
printError(err)
// Create a ticker that outputs elapsed time
ticker := time.NewTicker(time.Second)
go func(ticker *time.Ticker) {
now := time.Now()
for _ = range ticker.C {
printOutput(
[]byte(fmt.Sprintf(&quot;%s&quot;, time.Since(now))),
)
}
}(ticker)
// Create a timer that will kill the process
timer := time.NewTimer(time.Second * 4)
go func(timer *time.Timer, ticker *time.Ticker, cmd *exec.Cmd) {
for _ = range timer.C {
err := cmd.Process.Signal(os.Kill)
printError(err)
ticker.Stop()
}
}(timer, ticker, cmd)
// Only proceed once the process has finished
cmd.Wait()
printOutput(
[]byte(fmt.Sprintf(&quot;%d bytes generated!&quot;, len(randomBytes.Bytes()))),
)
// http://play.golang.org/p/tQRk1xJOqW
</code></pre>
<p>Now that was a lot more work but it all makes good sense. I started a computationaly difficult task of generating a collection of random bytes. Next I start that command asynchronously and then begin a ticker to show the elapsed time and a timer to kill the process after 4 seconds. Once the process has been killed then we output the total number of generated bytes.</p>
<p><em>A small disclaimer. I don&rsquo;t claim that this is the best way to do this but it demonstrates asynchronous commands and the ability to send signals to the process within our application.</em></p>
<h2 id="closing-comments:b15a4def803f966fde627651ff8cb67a">Closing comments</h2>
<p>This has been quite a technical post but we have covered lots of ground with the flexibility of <code>os/exec</code>. I have tested all the examples on my Mac using go1.3. Any suggestions/improvements are welcomed.</p>
<p>I hope I&rsquo;ve been able to get across why I&rsquo;m beginning to really enjoy working with Go.</p>
</description>
</item>
<item>
<title>Continuing Clojure</title>
<link>http://www.darrencoxall.com/clojure/continuing-clojure/</link>
<pubDate>Thu, 24 Jul 2014 21:59:27 +0100</pubDate>
<guid>http://www.darrencoxall.com/clojure/continuing-clojure/</guid>
<description>
<p>After getting the hang of some of the basics in my last article (<a href="http://www.darrencoxall.com/clojure/starting-clojure/" title="Getting started with Clojure">Starting Clojure</a>) I decided it was time to throw myself into some <em>slightly</em> more challenging puzzles. This post will be very code centric with some brief notes about what led me to my solutions/failures.</p>
<p>Still learning I turned to <a href="http://www.4clojure.com" title="Browser based Clojure challenges">4Clojure</a> which has some nice in browser challenges. I continued using LightPaper to experiment throughout as the lack of information can be annoying when starting.</p>
<h3 id="problem-21-nth-element:24cbdd6cdf252104eabe5bc43cd6c3e2">Problem 21: Nth Element</h3>
<p>This was the first problem my head refused to solve quickly. At first I considered using a for loop but that felt nasty and not particularly functional. Then the answer suddenly dawned on me (and it is particularly easy).</p>
<pre><code>#((vec %1) %2) ; equivalent to (nth vec i)
</code></pre>
<h3 id="problem-22-count-a-sequence:24cbdd6cdf252104eabe5bc43cd6c3e2">Problem 22: Count a sequence</h3>
<p>Now this time I liked the challenge and the first time I attempted it I had a google for some tips which helped immensely. The tip was that we are effectively going through a list to generate a single number. There&rsquo;s a common functional way of doing that.</p>
<pre><code>; reduce a seq but use 1 instead of the actual value
; I had to set the initial value to 0 to prevent inc \H
(fn [x] (reduce (fn [total s] (inc total)) 0 (seq x)))
</code></pre>
<h3 id="problem-23-reverse-a-sequence:24cbdd6cdf252104eabe5bc43cd6c3e2">Problem 23: Reverse a sequence</h3>
<p>This challenge I recognised I could use the difference between the different collection types and iteratively build a list using each of the elements in the set.</p>
<pre><code>#(reduce conj '() %)
; at this point I decided reduce is my friend
</code></pre>
<h3 id="problem-26-fibonacci:24cbdd6cdf252104eabe5bc43cd6c3e2">Problem 26: Fibonacci</h3>
<p>So this should be easy (and is when you know how) but it took me a while and it is solved in the official docs. I did pretty much copy it but I did make sure to learn how it worked and so please do the same.</p>
<pre><code>#(take %
;; take the first n results
(map first
;; take the first value of each fib pair
(iterate
;; infinitely add each result and the next number
(fn
[[a b]]
[b (+ a b)])
[1 1])))
;; seed the sequence with [1 1] (+ 1 1)
</code></pre>
<h3 id="problem-28-flatten-a-sequence:24cbdd6cdf252104eabe5bc43cd6c3e2">Problem 28: Flatten a Sequence</h3>
<p>Time to write our own <code>flatten</code>. I failed miserably here and cheated but the <a href="http://stackoverflow.com/questions/16155597/clojure-what-is-wrong-with-my-implementation-of-flatten">solution</a> my Google fu found did teach me some of the core functions I hadn&rsquo;t yet learnt and how they can be used.</p>
<pre><code>;; loop through the list applying concat
;; but recursive so we convert the elements
;; in the list to a concat'ed list
(fn x
[ls]
(if (sequential? ls)
(mapcat x ls)
(list ls)))
</code></pre>
<h3 id="problem-39-interleave-two-sequences:24cbdd6cdf252104eabe5bc43cd6c3e2">Problem 39: Interleave Two Sequences</h3>
<p>Without using the <code>interleave</code> method I was reminded of something I read about <code>map</code> which would allow me to combine the results of multiple sequences. I ended up using <code>map</code> and <code>flatten</code> to compress the final output. I&rsquo;m sure there are tidier ways of doing this that also support sequences of sequences.</p>
<pre><code>(fn [a b] (flatten (map (fn [x y] (list x y)) a b)))
</code></pre>
<h2 id="enough:24cbdd6cdf252104eabe5bc43cd6c3e2">Enough?</h2>
<p>So at this point in all honesty my attention was wavering. I had started to look into actual applications of the language including how best to test them.</p>
<p>I hope this hasn&rsquo;t been too tedious to read but often seeing solutions can help cement how flexible Clojure is and how all the core building blocks can fit together to solve very different problems.</p>
<p>If you have followed along and have gotten a better understanding of the language now is a good point to just dive in yourself. Keep the docs at hand and make a start at writing a trivial application.</p>
<p>Any future articles on Clojure will likely be focused on specific libraries (I&rsquo;m particularly interested in exploring the async features).</p>
<p>Once again my solutions are just that, mine. I&rsquo;m new to the language and so if you see something I could do better then comment as it is super helpful for me to see the <em>better</em> ways of achieving results.</p>
<p>Thanks for reading! I hope it helped.</p>
</description>
</item>
<item>
<title>Starting Clojure</title>
<link>http://www.darrencoxall.com/clojure/starting-clojure/</link>
<pubDate>Wed, 02 Jul 2014 20:44:08 +0100</pubDate>
<guid>http://www.darrencoxall.com/clojure/starting-clojure/</guid>
<description>
<p>I&rsquo;ve been developing Ruby for years now and I love it but I&rsquo;m getting too comfortable with it. I know as well as any good developer that it isn&rsquo;t the best tool for every job. It&rsquo;s my job to be able to build the right software the right way and that should include the language selection. So, time to take the plunge and learn another language from scratch.</p>
<h2 id="clojure-basics:9c0300697a63d0241134deb40fce7bdc">Clojure basics</h2>
<p>I selected Clojure because I find it interesting. There is something about its syntax that draws me too it. I&rsquo;ve been enjoying Go recently thanks to how easily I can write multi-threaded applications and so Clojure is also a good choice with immutable data structures.</p>
<p>So first place was to the <a href="http://clojure.org" title="Official Clojure Site">homepage</a>. I checked out a few of the tutorials and resources and settled on <a href="http://aphyr.com/posts/301-clojure-from-the-ground-up-welcome" title="Learning Clojure Guides">Clojure from the ground up</a>.</p>
<p>Following the instructions I installed <a href="http://leiningen.org/">Leiningen</a>, which seems to be a <code>Bundle</code> like tool for the language which is a relief for me as it also handles the installation of Clojure itself as well.</p>
<p>The inclusion of a REPL is a god-send to a developer like me learning as it means I can experiment quickly and learn the basics. I then also discovered <a href="http://www.lighttable.com/">Light Table</a> which includes a live REPL feature which is brilliant as it also allows you to indent the code making it much easier to read.</p>
<p>Slowly I can see the patterns in the language such as <code>conj</code> for inserting additional elements into lists/sets/vectors but the fact they all work slightly differently is &lsquo;nice to know&rsquo; now rather than later.</p>
<p>The first part that gets interesting (IMO) is the introduction of <code>lets</code> as this is where code re-use comes into play. Unfortunately the examples are lost on me a bit. My first question was how does let differ from just executing the code?</p>
<pre><code>(let [hello &quot;&quot;] (str &quot;Hello, &quot; hello &quot;!&quot;))
(hello &quot;Darren&quot;)
; CompilerException java.lang.RuntimeException: Unable to resolve symbol: hello in this context, compiling:(NO_SOURCE_PATH:0:0)
</code></pre>
<p>So how is the above useful? Well let looks as though it provides a context (I could be wrong, if so please correct me). The guide introduces <code>fn</code> so adapting my previous test:</p>
<pre><code>(let [hello (fn [name] (str &quot;Hello, &quot; name &quot;!&quot;))]
(hello &quot;Darren&quot;)) ; =&gt; &quot;Hello, Darren!&quot;
</code></pre>
<p>So that worked. After declaring a function I could re-use it within that particular expression. Moving on we are introduced to <code>def</code>.</p>
<pre><code>(def hello (fn [name] (str &quot;Hello, &quot; name &quot;!&quot;)))
(hello &quot;Darren&quot;) ; =&gt; &quot;Hello, Darren!&quot;
</code></pre>
<p>Now this feels closer to what I know (which can be further abbreviated using <code>defn</code>). I can now build re-usable components although this is the first introduction to something mutable within Clojure.</p>
<p>So continuing on I learn about supporting different arities and an introduction to some of the recursion functions. Now these are only starts but with them I could adjust my method to support multiple names.</p>
<pre><code>(defn hello
([name] (if (coll? name)
(str &quot;Hello, &quot; (apply str (interpose &quot;, &quot; name)) &quot;!&quot;)
(str &quot;Hey &quot; name &quot;!&quot;))))
(hello '(&quot;Darren&quot; &quot;Danika&quot;))
</code></pre>
<p>Or I could go a little step further&hellip;</p>
<pre><code>(defn human-list
([names]
(cond
(= (count names) 0) &quot;&quot;
(= (count names) 1) (peek names)
(&gt; (count names) 1) (str
(apply str
(interpose &quot;, &quot; (reverse (rest (reverse names)))))
&quot; and &quot; (peek (reverse names))))))
(human-list (list)) ; =&gt; &quot;&quot;
(human-list '(&quot;A&quot;)) ; =&gt; &quot;A&quot;
(human-list '(&quot;A&quot; &quot;B&quot;)) ; =&gt; &quot;A and B&quot;
(human-list '(&quot;A&quot; &quot;B&quot; &quot;C&quot;)) ; =&gt; &quot;A, B and C&quot;
(defn hello
([name] (if (coll? name)
(str &quot;Hello &quot; (human-list name) &quot;!&quot;)
(str &quot;Hey &quot; name &quot;!&quot;))))
(hello &quot;Darren&quot;) ; =&gt; &quot;Hey Darren!&quot;
(hello '(&quot;Darren&quot;)) ; =&gt; &quot;Hello Darren!&quot;
(hello '(&quot;Darren&quot; &quot;Danika&quot;)) ; =&gt; &quot;Hello Darren and Danika!&quot;
(hello '(&quot;Darren&quot; &quot;Danika&quot; &quot;George&quot;)) ; =&gt; &quot;Hello Darren, Danika and George!&quot;
</code></pre>
<p>I&rsquo;m enjoying the language although it is a stretch for me to do these things in a functional way and trying to avoid variables. Clojure does seem to encourage small abstractions as it can get difficult to read and follow when methods get large. That may well be because I&rsquo;m new to the language and do things in strange ways but it&rsquo;s all part of the learning experience right?</p>
</description>
</item>
<item>
<title>Cross Compiling Go Is Easy</title>
<link>http://www.darrencoxall.com/golang/cross-compiling-go-is-easy/</link>
<pubDate>Tue, 22 Oct 2013 19:17:00 +0000</pubDate>
<guid>http://www.darrencoxall.com/golang/cross-compiling-go-is-easy/</guid>
<description><p>I have found myself spending ever increasing amounts of time developing in Go (golang). Not because I need to, but because it&rsquo;s a refreshing change from my usual. One thing I was interested in however was simply getting my code to work <em>almost</em> anywhere which is harder with Go seeing as it needs a platform to target.</p>
<p>Initially I installed Go manually following the instructions on their website. I then started to see an abbreviation cropping up in places that caught my attention. <a href="https://github.com/moovweb/gvm" title="Go Version Manager">GVM (Go Version Manager)</a>. It is essentially the rbenv to ruby.</p>
<p>I won&rsquo;t put the installation instructions here. Don&rsquo;t be lazy just click through and have a read it is dead simple. My favourite feature of GVM wasn&rsquo;t the ease of installation as frankly Go is easy to install without it but the fact it rolled up all I needed to cross compile my code without me having to do any looking up. I just hacked together a bash script that would do the job for me.</p>
<p>First off set-up GVM and then install a version of Go. Then we can install the software required to compile for the various platforms. To do this I wrote the following:</p>
<pre><code>for GOOS in linux darwin windows
do
for GOARCH in amd64 386
do
gvm cross $GOOS $GOARCH
done
done
</code></pre>
<p>Once that is complete you should now be able to create a helper script to do the actual compilation. Feel free to customise to your needs.</p>
<pre><code>#!/bin/bash
APPNAME=example
for GOOS in linux darwin windows
do
for GOARCH in amd64 386
do
GO_ENABLED=0 GOOS=$GOOS GOARCH=$GOARCH go build -o &quot;bin/$APPNAME$GOOS-$GOARCH&quot; &quot;$APPNAME.go&quot;
done
done
</code></pre>
<p>Make the script executable and now you should have a very crude way of cross compiling your go projects.</p>
<p>Remember this isn&rsquo;t meant to be a one size fits all. It got me up and running quickly. There is almost certainly going to be a more comprehensive way of doing this but I didn&rsquo;t need it. All I needed were these few lines of bash and GVM.</p>
</description>
</item>
<item>
<title>Learning Ruby: Everything is an Object</title>
<link>http://www.darrencoxall.com/ruby/everything-is-an-object/</link>
<pubDate>Wed, 24 Jul 2013 20:17:00 +0000</pubDate>
<guid>http://www.darrencoxall.com/ruby/everything-is-an-object/</guid>
<description>
<p>The first thing to learn about Ruby is that <em>everything is an object</em>. The best way to make use of the languages features are to develop in an Object-Orientated way. This being the first article in many about learning Ruby, I will walk you through <em>classes</em> and <em>objects</em>. Ready?</p>
<p>If you would like to follow along make sure you install Ruby and then create a file called <code>learn_ruby_01.rb</code>.</p>
<h2 id="what-is-a-class:39aabd223f74e19e15ccec60af1d2d47">What is a Class?</h2>
<p>Classes in Ruby are basically containers. They store methods that can be used and provide systems in which to store data. The main use of a class is to define something that can be created multiple times, each time with it&rsquo;s own unique data.</p>
<p>Classes can be defined like so:</p>
<pre><code>class MyFirstClass
def hello
puts &quot;Hello, World!&quot;
end
end
</code></pre>
<p>The first line declares the class name (&lsquo;MyFirstClass&rsquo; in this example). Everything between this and <code>end</code> is the class definition. The definition in my example has a <code>hello</code> method indicated by the <code>def</code> (I believe it stands for define). Everything between the define and the next <code>end</code> is contained in the <code>hello</code> method.</p>
<p>On line 3 we call a method called <code>puts</code> with the text &ldquo;Hello, World!&rdquo;. This line will output the text to the terminal/console window.</p>
<p>Putting it all together we can see that we have a class called MyFirstClass which has 1 method - <code>hello</code> - which will put &ldquo;Hello, World!&rdquo; in the terminal when called.</p>
<h2 id="what-is-an-object:39aabd223f74e19e15ccec60af1d2d47">What is an Object?</h2>
<p>Continuing from our previous example we now create an <em>object</em> of <code>MyFirstExample</code>. To do that add the following to the bottom of our example file.</p>
<pre><code>class MyFirstClass
def hello
puts &quot;Hello, World!&quot;
end
end
# This is a comment. Below we create an object.
object = MyFirstObject.new
object.hello
</code></pre>
<p>If you now run our file with <code>ruby /path/to/example.rb</code> you will see that it outputs &ldquo;Hello, World!&rdquo;.</p>
<p>We&rsquo;ve created our own class but Ruby provides many to begin with. In-fact we have used 3 in our example:</p>
<ol>
<li><code>puts</code> is a method on a class called <code>Object</code> which is what amost everything in Ruby branches from.</li>
<li>We pass text to the <code>puts</code> method but the text itself is an object of a class called <code>String</code>. Strings are just a code representation of text. Another way of showing this is <code>String.new(&quot;Hello, World!&quot;)</code>.</li>
<li>Obviously the third is our own class - <code>MyFirstClass</code>.</li>
</ol>
<p>Ruby has a great many classes to help us start. Below is an example of a small number available to us:</p>
<pre><code># Numeric represents numbers
# It has many subclasses such as:
234.class # =&gt; Fixnum - integers
234.56.class # =&gt; Float - decimals
# Array represents lists of objects
[1,2,3].class # =&gt; Array
[&quot;sentence one&quot;, &quot;sentence two&quot;].class # =&gt; Array
# Hash represents a list of key value pairs
{ :key_name =&gt; &quot;key value&quot; }.class # =&gt; Hash
{ &quot;text key&quot; =&gt; 1234 }.class # =&gt; Hash
# Even the current script is a class
self.class # =&gt; Object
</code></pre>
<p>Next time we will look at ways we can add to classes both our own and the core classes. For now though let&rsquo;s recap. We have learnt that we can use classes to group and represent logic and code. We can create instances of classes - known as objects - which can call the defined methods. Finally we have also learnt that Ruby has many classes ready for us to use right away.</p>
<p>Thanks for reading!</p>
</description>
</item>
<item>
<title>Getting to know Go (Golang)</title>
<link>http://www.darrencoxall.com/golang/getting-to-know-go/</link>
<pubDate>Tue, 02 Apr 2013 08:00:00 +0000</pubDate>
<guid>http://www.darrencoxall.com/golang/getting-to-know-go/</guid>
<description>
<p>Being ever on the lookout for cool technologies, I stumbled upon the wonderful new <em>language</em> &lsquo;<a href="http://golang.org/" title="Golang">Go</a>&rsquo;. Developed by Google as a means of combatting the flaws and shortcomings of current languages such as Java and C++ when it comes to highly concurrent requirements.</p>
<p>Go <em>(or Golang as it is often referred to)</em> is a strong typed, compiled language. It was built from the ground up for concurrency and thread-safety support. The brilliant standard library utilises this and in doing so makes it extremely easy to develop concurrent applications.</p>
<p>There are numerous <em>hard-edge</em> decisions made with the language including the very C like object system and a unique function visibility system. Go is an object orientated language but the method/function definitions are much more explicit&hellip;</p>
<pre><code>// DoSomething operates on an object of type MyObject
// and accepts a string parameter.
// The function will return a boolean.
func (obj MyObject) DoSomething(name string) (bool) {
// ...
}
</code></pre>
<p>The system used to determine function visibility is also <em>different</em> to the tried and tested. Functions and variables that begin with a lowercase character are only accessible within their package whereas those beginning with an uppercase character are usable elsewhere.</p>
<h2 id="what-am-i-doing-with-go:fe2cccec5024f852eeb2b45cb4bebf66">What am I doing with Go?</h2>
<p>I am currently in the process of writing a web application consisting of an API and a JavaScript front-end. I was leaning towards using Ruby on Rails but when I am just creating an API many of the features provided by Rails are un-necessary. It brings with it a larger overhead. I have always been aware of this but it wasn&rsquo;t until I saw a <a href="http://www.techempower.com/blog/2013/03/28/framework-benchmarks/" title="Framework Benchmarks">recent benchmark</a> that I was encouraged to look elsewhere, after all, I should be selecting the best tool for the job not forcing my favourite tool to do everything. The results of the benchmark gave me an excuse to check out Go.</p>
<p><em>Before any complaints - I will be the first to say comparing Go to Rails is un-fair. Rails is a framework and Go is a language. I know this but it still allows me to question if a large framework is needed on a project that has just a single JSON API. I decided the answer was No.</em></p>
<h2 id="my-opinions-thoughts:fe2cccec5024f852eeb2b45cb4bebf66">My opinions &amp; thoughts</h2>
<p>Coming from a Ruby background Go was certainly a big change but I like a good challenge. It is easy to forget how much is handled for you when using a large framework such as Rails. Go does very little for you. Even with a fantastic standard library and brilliant documentation, there is a lot more to be done in Go to create a working web application.</p>
<p>There is a benefit to working from the core up. You get 100% control over which features you include and how much configuration your application <em>actually</em> requires. Go will even go as far as formatting your code so the real development time is spent designing and implementing your application. There are no frameworks that you have to work around.</p>
<p>By developing in this way using Go you can gain massive <a href="http://blog.iron.io/2013/03/how-we-went-from-30-servers-to-2-go.html" title="Performance Improvements using Go">performance improvements</a> and start leveraging modern hardware using concurrency.</p>
<p>I am really enjoying Go and I hope to continue developing with it in the future. It doesn&rsquo;t feel like a language designed for traditional web applications such as Rails but it does have many strengths that make it a much better option for more streamlined services.</p>
<h3 id="closing-comments:fe2cccec5024f852eeb2b45cb4bebf66">Closing Comments</h3>
<p>I hope this article does highlight why as developers we should be looking to constantly learn. We shouldn&rsquo;t have a single language or framework that we believe has everything because it frankly doesn&rsquo;t exist. The best tool is completely opinionated and is determined by the project and the environment in which it is developed.</p>
<p>Oh… And Go is super cool and quick. Remember that it is a language and isn&rsquo;t designed for just web applications but <em>applications</em> in general.</p>
<p><strong>EDIT:</strong> I have created a basic vagrant repository that can help people by installing and preparing a golang environment. Check out <a href="https://github.com/dcoxall/vagrant-golang" title="dcoxall/vagrant-golang">vagrant-golang</a></p>
</description>
</item>
<item>
<title>Boxen and My Experience</title>
<link>http://www.darrencoxall.com/tools/boxen-and-my-experience/</link>
<pubDate>Sun, 03 Mar 2013 15:00:00 +0000</pubDate>
<guid>http://www.darrencoxall.com/tools/boxen-and-my-experience/</guid>
<description>
<p><a href="https://github.com/boxen" title="Boxen">Boxen</a> is a new tool that allows new Macs to be quickly set-up using the same technologies that sysops have become accustomed to, Puppet. Now Puppet has it&rsquo;s own language to define what actions are executed on target machine. It was originally developed to help prepare <em>cloud</em> servers for easier management/deployment.</p>
<p>The popularity of Puppet has increased and it has become a widely used tool and so the team over at <a href="https://github.com/" title="GitHub">github.com</a> decided to build a system that utilises it to perform similar setup tasks on Macs.</p>
<p>I have only spent a couple of days using Boxen but it has given me some fairly strong opinion. Before I dive in with my thoughts I must own up to <em>(still)</em> not completely understanding the Puppet language and this is likely a large cause of many of my issues.</p>
<h2 id="developing-for-boxen:d409599d847cdf6f6abf21fe7800a8cc">Developing for Boxen</h2>
<p>Getting started with Boxen is quick and easy. Following the provided instructions works perfectly. The pre-made puppet classes and libraries developed for Boxen all seem to work brilliantly. I had only minor issues with 1 of the repos but this was easy to get around.</p>
<p>The difficulty comes when creating your own Puppet modules. I had trouble figuring out how to test that the documents worked as expected. Running boxen, having it install multiple pieces of software and tools only for it to fail near the end. This wouldn&rsquo;t be so bad but a couple of pre-flight checks built into Boxen meant I would have to uninstall the software to retry. This became a pain. Many of you may read this and think:</p>
<blockquote>
<p>Why not just remove the checks? It&rsquo;s all open source after all.</p>
</blockquote>