├── .gitignore ├── Gemfile ├── favicon.ico ├── _config.yml ├── javascripts ├── scale.fix.js └── sidebar.js ├── ignore.html ├── pages ├── table-of-contents.md ├── template.md ├── explanation.md ├── controlling-ec2-from-the-console.md ├── creating-a-production-storm-cluster.md ├── retrieving-storm-data-from-nimbus.md ├── installing-mysql.md └── hello-world.md ├── README.md ├── Gemfile.lock ├── Rakefile ├── index.md ├── stylesheets ├── pygment_trac.css └── styles.css └── _layouts └── default.html /.gitignore: -------------------------------------------------------------------------------- 1 | .rvmrc 2 | _site/ 3 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source :rubygems 2 | 3 | gem 'fileutils' 4 | gem 'jekyll' 5 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tutorials/tutorials.github.com/master/favicon.ico -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | pygments: true 2 | markdown: kramdown 3 | 4 | tracking_id: UA-30727234-1 5 | -------------------------------------------------------------------------------- /javascripts/scale.fix.js: -------------------------------------------------------------------------------- 1 | fixScale = function(doc) { 2 | 3 | var addEvent = 'addEventListener', 4 | type = 'gesturestart', 5 | qsa = 'querySelectorAll', 6 | scales = [1, 1], 7 | meta = qsa in doc ? doc[qsa]('meta[name=viewport]') : []; 8 | 9 | function fix() { 10 | meta.content = 'width=device-width,minimum-scale=' + scales[0] + ',maximum-scale=' + scales[1]; 11 | doc.removeEventListener(type, fix, true); 12 | } 13 | 14 | if ((meta = meta[meta.length - 1]) && addEvent in doc) { 15 | fix(); 16 | scales = [.25, 1.6]; 17 | doc[addEvent](type, fix, true); 18 | } 19 | 20 | }; -------------------------------------------------------------------------------- /ignore.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | Google Analytics will now ignore you. 17 | 18 | 19 | -------------------------------------------------------------------------------- /pages/table-of-contents.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Table of Contents 4 | ignore: true 5 | --- 6 | 7 | # All Tutorials 8 | 9 | 10 | 11 | 12 | * [Controlling EC2 from the Console](/pages/controlling-ec2-from-the-console.html?ts=1340509738) 13 | * [Creating a Production Storm Cluster](/pages/creating-a-production-storm-cluster.html?ts=1340487894) 14 | * [Retrieving Storm Cluster Statistics from Nimbus](/pages/retrieving-storm-data-from-nimbus.html?ts=1340398351) 15 | * [Installing MySQL](/pages/installing-mysql.html?ts=1339980010) 16 | * [Hello, World!](/pages/hello-world.html?ts=1339978842) 17 | 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | tutorials.github.com 2 | ==================== 3 | 4 | tutorials.github.com is a simple hack that uses GitHub Pages to fulfill a need of mine: collecting disparate tutorials and allowing others to easily fork them so the full range of languages and systems is covered. 5 | 6 | Examples 7 | ======== 8 | 9 | * [Installing MySQL](http://tutorials.github.com/pages/installing-mysql.html) 10 | * [Hello, World!](http://tutorials.github.com/pages/hello-world.html "Hello, World!") 11 | * [Syntax explanation](http://tutorials.github.com/pages/explanation.html) 12 | 13 | Contributing 14 | ============ 15 | 16 | - Fork this repo 17 | - Add a new file 18 | - Send me a pull request 19 | 20 | Note: This project is not affiliated with GitHub Inc. 21 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | albino (1.3.3) 5 | posix-spawn (>= 0.3.6) 6 | classifier (1.3.3) 7 | fast-stemmer (>= 1.0.0) 8 | directory_watcher (1.4.1) 9 | fast-stemmer (1.0.1) 10 | fileutils (0.7) 11 | rmagick (>= 2.13.1) 12 | jekyll (0.11.2) 13 | albino (~> 1.3) 14 | classifier (~> 1.3) 15 | directory_watcher (~> 1.1) 16 | kramdown (~> 0.13) 17 | liquid (~> 2.3) 18 | maruku (~> 0.5) 19 | kramdown (0.13.7) 20 | liquid (2.3.0) 21 | maruku (0.6.0) 22 | syntax (>= 1.0.0) 23 | posix-spawn (0.3.6) 24 | rmagick (2.13.1) 25 | syntax (1.0.0) 26 | 27 | PLATFORMS 28 | ruby 29 | 30 | DEPENDENCIES 31 | fileutils 32 | jekyll 33 | -------------------------------------------------------------------------------- /pages/template.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Template 4 | ignore: true 5 | --- 6 | 7 | # Page Title 8 | 9 | Introductory content: Salvia freegan pickled post-ironic. Hoodie mcsweeney's beard, lomo aesthetic semiotics echo park pitchfork typewriter. Fanny pack organic 3 wolf moon shoreditch. Swag cardigan thundercats, marfa authentic fap gastropub small batch scenester. 10 | 11 | Portland quinoa hella. Biodiesel forage pickled bushwick fingerstache godard. Put a bird on it tofu aesthetic organic flexitarian. 12 | 13 | Now here are two tutorials: 14 | 15 |
16 | ## Ruby and JRuby 17 | 18 | {% highlight ruby %} 19 | puts "Hello, World!" 20 | {% endhighlight %} 21 |
22 | 23 |
24 | ## C 25 | 26 | {% highlight c %} 27 | #include 28 | 29 | int main(void) 30 | { 31 | printf("Hello, World!"); 32 | return 0; 33 | } 34 | {% endhighlight %} 35 |
36 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'rake' 3 | 4 | task :default => :update_toc 5 | 6 | desc "Regenerate the table of contents to include links to newest tutorials" 7 | task :update_toc do 8 | require 'jekyll' 9 | require 'tempfile' 10 | require 'fileutils' 11 | 12 | site = Jekyll::Site.new(Jekyll.configuration({})) and site.read 13 | 14 | pages = site.pages.reject do |page| 15 | page.data["ignore"] 16 | end.sort_by! do |page| 17 | File.mtime(File.join(FileUtils.pwd, "pages", page.name)).to_i 18 | end.reverse 19 | 20 | toc_path = File.join(FileUtils.pwd, "pages", "table-of-contents.md") 21 | temp = Tempfile.new("table_of_contents.md") 22 | 23 | begin 24 | File.readlines(toc_path).each do |line| 25 | line =~ /^$/ ? break : temp.puts(line) 26 | end 27 | temp.puts "" 28 | pages.each_with_index do |page, index| 29 | temp.puts "* [#{page.data["title"]}](#{page.destination('')}?ts=#{File.mtime(File.join(FileUtils.pwd, "pages", page.name)).to_i})" 30 | end 31 | temp.puts "" 32 | FileUtils.mv(temp.path, toc_path) 33 | ensure 34 | temp.delete 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Decentralized Polyglot Tutorials 4 | ignore: true 5 | --- 6 | 7 | README 8 | ====== 9 | 10 | tutorials.github.com is a simple hack that uses GitHub Pages to fulfill a need of mine: collecting disparate tutorials and allowing others to easily fork them so the full range of languages and systems is covered. 11 | 12 | For now, each topic is its own page, and you use the sidebar navigation to drill down into a variant that's most useful to you. It might not look like it, but __the navigation is clickable!__ Try clicking on a language in the [Hello, World!](/pages/hello-world.html) example to get a feel for the navigation. 13 | 14 | In the future, I'll add cookies so the site will apply filters for you and a central collection of tags/values so we have some consistency across various tutorials. 15 | 16 | This project originated as a full-blown rails app backed by a database, and I reached a point where I needed user accounts and git repos. Dreading that, I threw it all away for a simpler, git-based workflow to upload data. I sincerely hope you enjoy it and find it useful. 17 | 18 | All Tutorials 19 | ------------- 20 | You can [browse all tutorials here](/pages/table-of-contents.html?ts=1340509738). 21 | 22 | Newest Tutorials 23 | ---------------- 24 | * [Controlling EC2 from the Console](/pages/controlling-ec2-from-the-console.html?ts=1340509738) 25 | * [Creating a Production Storm Cluster](/pages/creating-a-production-storm-cluster.html?ts=1340499018) 26 | * [Retrieving Storm Cluster Statistics from Nimbus](/pages/retrieving-storm-data-from-nimbus.html?ts=1340499018) 27 | * [Installing MySQL](/pages/installing-mysql.html?ts=1340499018) 28 | * [Hello, World!](/pages/hello-world.html?ts=1340499018) 29 | 30 | Examples 31 | -------- 32 | * [Installing MySQL](/pages/installing-mysql.html?ts=1340499018) 33 | * [Hello, World!](/pages/hello-world.html?ts=1340499018) 34 | * [Syntax explanation](/pages/explanation.html?ts=1340499018) 35 | 36 | Contributing 37 | ------------ 38 | 39 | - Fork this repo 40 | - Add a new file (or modify an existing one) 41 | - Send me a pull request 42 | 43 | Note: This project is not affiliated with GitHub Inc. 44 | -------------------------------------------------------------------------------- /stylesheets/pygment_trac.css: -------------------------------------------------------------------------------- 1 | .highlight { background: #ffffff; } 2 | .highlight span.c { color: #999988; font-style: italic } /* Comment */ 3 | .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ 4 | .highlight .k { font-weight: bold } /* Keyword */ 5 | .highlight .o { font-weight: bold } /* Operator */ 6 | .highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ 7 | .highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ 8 | .highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ 9 | .highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ 10 | .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ 11 | .highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ 12 | .highlight .ge { font-style: italic } /* Generic.Emph */ 13 | .highlight .gr { color: #aa0000 } /* Generic.Error */ 14 | .highlight .gh { color: #999999 } /* Generic.Heading */ 15 | .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ 16 | .highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ 17 | .highlight .go { color: #888888 } /* Generic.Output */ 18 | .highlight .gp { color: #555555 } /* Generic.Prompt */ 19 | .highlight .gs { font-weight: bold } /* Generic.Strong */ 20 | .highlight .gu { color: #800080; font-weight: bold; } /* Generic.Subheading */ 21 | .highlight .gt { color: #aa0000 } /* Generic.Traceback */ 22 | .highlight .kc { font-weight: bold } /* Keyword.Constant */ 23 | .highlight .kd { font-weight: bold } /* Keyword.Declaration */ 24 | .highlight .kn { font-weight: bold } /* Keyword.Namespace */ 25 | .highlight .kp { font-weight: bold } /* Keyword.Pseudo */ 26 | .highlight .kr { font-weight: bold } /* Keyword.Reserved */ 27 | .highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ 28 | .highlight .m { color: #009999 } /* Literal.Number */ 29 | .highlight span.s { color: #d14 } /* Literal.String */ 30 | .highlight .na { color: #008080 } /* Name.Attribute */ 31 | .highlight .nb { color: #0086B3 } /* Name.Builtin */ 32 | .highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ 33 | .highlight .no { color: #008080 } /* Name.Constant */ 34 | .highlight .ni { color: #800080 } /* Name.Entity */ 35 | .highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ 36 | .highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ 37 | .highlight .nn { color: #555555 } /* Name.Namespace */ 38 | .highlight .nt { color: #000080 } /* Name.Tag */ 39 | .highlight .nv { color: #008080 } /* Name.Variable */ 40 | .highlight .ow { font-weight: bold } /* Operator.Word */ 41 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */ 42 | .highlight .mf { color: #009999 } /* Literal.Number.Float */ 43 | .highlight .mh { color: #009999 } /* Literal.Number.Hex */ 44 | .highlight .mi { color: #009999 } /* Literal.Number.Integer */ 45 | .highlight .mo { color: #009999 } /* Literal.Number.Oct */ 46 | .highlight .sb { color: #d14 } /* Literal.String.Backtick */ 47 | .highlight .sc { color: #d14 } /* Literal.String.Char */ 48 | .highlight .sd { color: #d14 } /* Literal.String.Doc */ 49 | .highlight .s2 { color: #d14 } /* Literal.String.Double */ 50 | .highlight .se { color: #d14 } /* Literal.String.Escape */ 51 | .highlight .sh { color: #d14 } /* Literal.String.Heredoc */ 52 | .highlight .si { color: #d14 } /* Literal.String.Interpol */ 53 | .highlight .sx { color: #d14 } /* Literal.String.Other */ 54 | .highlight .sr { color: #009926 } /* Literal.String.Regex */ 55 | .highlight .s1 { color: #d14 } /* Literal.String.Single */ 56 | .highlight .ss { color: #990073 } /* Literal.String.Symbol */ 57 | .highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ 58 | .highlight .vc { color: #008080 } /* Name.Variable.Class */ 59 | .highlight .vg { color: #008080 } /* Name.Variable.Global */ 60 | .highlight .vi { color: #008080 } /* Name.Variable.Instance */ 61 | .highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ 62 | 63 | .type-csharp .highlight .k { color: #0000FF } 64 | .type-csharp .highlight .kt { color: #0000FF } 65 | .type-csharp .highlight .nf { color: #000000; font-weight: normal } 66 | .type-csharp .highlight .nc { color: #2B91AF } 67 | .type-csharp .highlight .nn { color: #000000 } 68 | .type-csharp .highlight .s { color: #A31515 } 69 | .type-csharp .highlight .sc { color: #A31515 } 70 | -------------------------------------------------------------------------------- /_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {% if page.title %} 7 | {{ page.title }} - tutorials.github.com 8 | {% else %} 9 | tutorials.github.com 10 | {% endif %} 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 33 | 34 | 35 |
36 | Fork me on GitHub 37 |
38 |
39 |

tutorials.github.com

40 |

Decentralized polyglot tutorials

41 | 42 |
43 |
44 |
45 | {{ content }} 46 |
47 | 68 |
69 | 70 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /pages/explanation.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Test 4 | ignore: true 5 | --- 6 | 7 | # How tutorials.github.com Works 8 | 9 | This site works by using [Github Pages](http://pages.github.com/) to automatically generate and serve content. Github Pages works by using by using [Jekyll](https://github.com/mojombo/jekyll), a "blog-aware, static site generator in Ruby." Since it's a completely static site, all interactions are done through javascript on a per-page basis. 10 | 11 | ## Location and Markup Language 12 | 13 | All tutorials are stored in the `/pages` subdirectory of the repo. Although jekyll supports several different markup languages such as markdown, textile, etc., tutorials.github.com has only been tested using markdown (for now). 14 | 15 | ## Syntax 16 | 17 | Since Github Pages are (unfortunately) not parsed using [Github Flavored Markdown](http://github.github.com/github-flavored-markdown/), we use the [kramdown](https://github.com/gettalong/kramdown)'s extended markdown syntax to enable things like syntax highlighting and allowing markdown parsing _within_ an html tag. 18 | 19 | ## Structure 20 | 21 | Tutorials have, at a minimum, the following structure: 22 | 23 | {% highlight html %} 24 |
25 | some _markdown_ content 26 |
27 | {% endhighlight %} 28 | 29 | Let's explore each in more detail. 30 | 31 | ### data-facets 32 | 33 | These data attributes that are used to list key-value pairs that javascript uses to "facet" the document with. We store JSON because jQuery automatically converts HTML5 data attributes into `camelCase`, so we'd lose formatting. 34 | 35 | ### markdown="1" 36 | 37 | The `markdown="1"` attribute to tell kramdown to parse the content of the divs as markdown instead. Because of this internal parsing, is it recommended to outdent the content inside the div (that is, type your content without leading whitespace), like in the example above. 38 | 39 | ### class="tutorial" 40 | 41 | Tutorial divs should have `class="tutorial"` to separate them from internally-nested divs. I haven't tested nesting divs, but they should work. 42 | 43 | ## Faceting 44 | 45 | We parse all the tutorials on a page and generate a sidebar so that users can drill-down to the most relevant tutorial. For example, a document like this: 46 | 47 | {% highlight html %} 48 |
49 | ... 50 |
51 | 52 |
53 | ... 54 |
55 | 56 |
57 | ... 58 |
59 | {% endhighlight %} 60 | 61 | should show the following sidebar: 62 | 63 | Operating System (2) 64 | OS X (2) 65 | Ubuntu (1) 66 | 67 | Package Management (3) 68 | Homebrew (1) 69 | Macports (1) 70 | Source (1) 71 | 72 | If you clicked on the "Source (1)" `li` then you should see this: 73 | 74 | Operating System (1) 75 | Ubuntu (1) 76 | 77 | Package Management (3) 78 | Source 79 | 80 | ## Installing tutorials.github.com Locally 81 | 82 | First you need to [fork the repo](https://github.com/tutorials/tutorials.github.com/fork_select). Then you need to clone your fork and checkout a topic-branch: 83 | 84 | {% highlight sh %} 85 | git clone git@github.com:some_user/tutorials.github.com.git 86 | cd tutorials.github.com 87 | git checkout -b my-awesome-tutorial 88 | {% endhighlight %} 89 | 90 | Now we need to install some gems using bundler: 91 | 92 | {% highlight sh %} 93 | bundle 94 | {% endhighlight %} 95 | 96 | Then start the jekyll server: 97 | 98 | {% highlight sh %} 99 | jekyll --server --auto 100 | {% endhighlight %} 101 | 102 | Now you can browse to [http://localhost:4000](http://localhost:4000) and see the site running locally. 103 | 104 | ## Creating a New Tutorial 105 | 106 | Creating a new tutorial is easy. All you need to do is create a new file in the `pages` directory, but it's a lot easier if you just start from the `template.md` file: 107 | 108 | {% highlight sh %} 109 | cp pages/template.md pages/my-new-tutorial.md 110 | {% endhighlight %} 111 | 112 | Then just follow the guide and `pages/hello-world.md` as an example. 113 | 114 | Once you're done (and it looks good when running locally), send me a pull request and I'll merge in your new page, regenerate the table of contents and other cleanup, and then push it to github. 115 | -------------------------------------------------------------------------------- /pages/controlling-ec2-from-the-console.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Controlling EC2 from the Console 4 | --- 5 | 6 | # Controlling EC2 from the Console 7 | 8 | [Amazon Web Services'](http://aws.amazon.com/) [Elastic Compute Cloud](http://aws.amazon.com/ec2/) is a web service that provides resizable compute capacity in the cloud. It is designed to make web-scale computing easier for developers. 9 | 10 | You can control your EC2 instances through the [AWS Management Console](https://console.aws.amazon.com/ec2/), but clicking around can be a chore. This tutorial will help you setup your machine so you can spawn new instances, query existing instances, and do general maintainence without leaving the comfort of a terminal. 11 | 12 |
18 | 19 | ## Assumptions 20 | We assume you've [signed up for EC2](https://aws-portal.amazon.com/gp/aws/developer/registration). We also assume your machine has a public key setup (commonly `~/.ssh/id_rsa` and `~/id_rsa.pub`). 21 | 22 | ## Download Credential Files 23 | First, you need to download some credential files to your machine. Go to the [AWS Security Credentials](https://portal.aws.amazon.com/gp/aws/securityCredentials) page, click "X.509 Certificates", create a new certificate if you need to, download the files when prompted, and then put them into your `~/.ec2` directory: 24 | 25 | {% highlight sh %} 26 | mkdir ~/.ec2 27 | cp ~/Downloads/{cert,pk}-*.pem ~/.ec2 28 | {% endhighlight %} 29 | 30 | ## Install the EC2 Command Line Tools 31 | Now let's install the two packages we need: 32 | 33 | {% highlight sh %} 34 | brew install ec2-{api,ami}-tools 35 | {% endhighlight %} 36 | 37 | Copy the following to your `~/.bash_profile`: 38 | 39 | {% highlight sh %} 40 | export JAVA_HOME="$(/usr/libexec/java_home)" 41 | export EC2_PRIVATE_KEY="$(/bin/ls "$HOME"/.ec2/pk-*.pem | /usr/bin/head -1)" 42 | export EC2_CERT="$(/bin/ls "$HOME"/.ec2/cert-*.pem | /usr/bin/head -1)" 43 | export EC2_HOME="/usr/local/Library/LinkedKegs/ec2-api-tools/jars" 44 | export AWS_ACCESS_KEY_ID="..." 45 | export AWS_SECRET_ACCESS_KEY"=..." 46 | {% endhighlight %} 47 | 48 | Where `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` are available from the "Access Keys" tab on the [https://portal.aws.amazon.com/gp/aws/securityCredentials](Amazon Security Credentials page). 49 | 50 | Don't forget to reload your `.bash_profile`: 51 | 52 | {% highlight sh %} 53 | source ~/.bash_profile 54 | {% endhighlight %} 55 | 56 | ## Uploading your Access Keys 57 | Some people use the public/private keys that Amazon gives them, but I find it easier to use the same public key on my laptop that I already use for things like Github and servers at work. To upload, you can use [this helpful script from Eric Hammond](http://alestic.com/2010/10/ec2-ssh-keys) (slightly modified): 58 | 59 | {% highlight sh %} 60 | keypair=macbook # Choose something that makes sense, like your computer name 61 | publickeyfile=$HOME/.ssh/id_rsa.pub # Point this to the public key you want to use 62 | regions=$(ec2-describe-regions | cut -f2) 63 | 64 | for region in $regions; do 65 | echo $region 66 | ec2-import-keypair --region $region --public-key-file $publickeyfile $keypair 67 | done 68 | {% endhighlight %} 69 | 70 | If you get an error like this, you have to wait a little while until Amazon processes your account: 71 | 72 | Client.OptInRequired: You are not subscribed to this service. Please go to http://aws.amazon.com to subscribe. 73 | 74 | ## Test it All Works 75 | Once we've done all that, we can test it by doing: 76 | 77 | {% highlight sh %} 78 | ec2-describe-instances 79 | {% endhighlight %} 80 | 81 | If you don't see an error, you're all set! 82 | 83 | ## Further Reading 84 | Since there are almost 300 commands available to you now, your best bet is to take a look at the [EC2 Command Line Reference](http://docs.amazonwebservices.com/AWSEC2/latest/CommandLineReference/Welcome.html). One command that you'll want to memorize is [ec2-run-instances](http://docs.amazonwebservices.com/AWSEC2/latest/CommandLineReference/ApiReference-cmd-RunInstances.html), which will spawn a new ec2 instance when you give it an amazon machine image (AMI) id. 85 | 86 | ## References 87 | These links were helpful in getting my machine setup and writing this tutorial: 88 | 89 | * [Starting Amazon EC2 with Mac OS X](http://www.robertsosinski.com/2008/01/26/starting-amazon-ec2-with-mac-os-x/) 90 | * [Uploading Personal ssh Keys to Amazon EC2](http://alestic.com/2010/10/ec2-ssh-keys) 91 |
92 | -------------------------------------------------------------------------------- /pages/creating-a-production-storm-cluster.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Creating a Production Storm Cluster 4 | --- 5 | 6 | # Creating a Production Storm Cluster 7 | 8 | [Storm](http://storm-project.net/) is a [free and open source](http://storm-project.net/about/free-and-open-source.html) distributed realtime computation system. Storm makes it easy to reliably process unbounded streams of data, doing for realtime processing what Hadoop did for batch processing. Storm is [simple](http://storm-project.net/about/simple-api.html), can be used with [any programming language](http://storm-project.net/about/multi-language.html), and is a lot of fun to use! 9 | 10 | This tutorial will help you set up a production storm cluster from scratch. 11 | 12 |
18 | 19 | ## Assumptions 20 | We assume you have two machines that you can ssh into as the `deploy` user, and that user has `sudo` privleges. We'll call these machines `storm` and `zookeeper`. It's ok if you only have one machine, this tutorial will handle that case as well. 21 | 22 | ## Java 23 | 24 | We need to install the JDK (which includes the JRE). Oracle requires you accept the license agreement, so I prefer to download this locally and then `scp` the file to my host. To download the JDK, go to [the jdk download page](http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1637583.html), accept the license agreement, and download the file called `jdk-7u5-linux-x64.rpm`. Then copy it to the `deploy` user's home directory using `scp`: 25 | 26 | {% highlight sh %} 27 | scp -C jdk-7u5-linux-x64.rpm deploy@zookeeper:/home/deploy 28 | scp -C jdk-7u5-linux-x64.rpm deploy@storm:/home/deploy 29 | {% endhighlight %} 30 | 31 | Then we install it on each machine (and setup our `JAVA_HOME` and `PATH` to find all the java binaries): 32 | 33 | {% highlight sh %} 34 | ssh zookeeper 35 | sudo rpm -Uvh jdk-7u5-linux-x64.rpm 36 | echo "export JAVA_HOME=/usr/java/default \ 37 | export PATH=$PATH:$JAVA_HOME/bin:$HOME/bin" > ~/.bash_profile 38 | logout 39 | 40 | ssh storm 41 | sudo rpm -Uvh jdk-7u5-linux-x64.rpm 42 | echo "export JAVA_HOME=/usr/java/default \ 43 | export PATH=$PATH:$JAVA_HOME/bin:$HOME/bin" > ~/.bash_profile 44 | logout 45 | {% endhighlight %} 46 | 47 | ## Zookeeper 48 | 49 | ### Installing Dependencies 50 | 51 | First we need to install some dependencies and setup a place to keep our source files: 52 | 53 | {% highlight sh %} 54 | ssh deploy@zookeeper 55 | mkdir -p ~/src 56 | sudo yum install -y libtool libuuid-devel gcc-c++ make 57 | {% endhighlight %} 58 | 59 | ### Installing Zookeeper 60 | 61 | Now we're ready to install zookeeper: 62 | 63 | {% highlight sh %} 64 | cd ~/src 65 | wget http://mirrors.axint.net/apache/zookeeper/zookeeper-3.4.3/zookeeper-3.4.3.tar.gz 66 | tar xzf zookeeper-3.4.3.tar.gz 67 | {% endhighlight %} 68 | 69 | ### Running Zookeeper 70 | 71 | Zookeeper is configured by a file located in `conf/zookeper.conf`. We'll use this as our zookeeper config when we start the zookeeper server: 72 | 73 | {% highlight sh %} 74 | ~/src/zookeeper-3.4.3/bin/zkServer.sh start ~/src/zookeeper-3.4.3/conf/zoo_sample.cfg 75 | {% endhighlight %} 76 | 77 | ## Storm 78 | 79 | Now that zookeeper is running, we can setup our storm servers. First we need to [install native dependencies](https://github.com/nathanmarz/storm/wiki/Installing-native-dependencies): 80 | 81 | ### Installing Dependencies 82 | 83 | {% highlight sh %} 84 | ssh deploy@zookeeper 85 | sudo yum install -y git libtool libuuid-devel gcc-c++ make 86 | mkdir -p ~/src /tmp/storm 87 | {% endhighlight %} 88 | 89 | ### Installing ZeroMQ 90 | 91 | {% highlight sh %} 92 | cd ~/src 93 | wget http://download.zeromq.org/zeromq-2.1.7.tar.gz 94 | tar xzf zeromq-2.1.7.tar.gz 95 | cd zeromq-2.1.7 96 | ./configure 97 | make 98 | sudo make install 99 | {% endhighlight %} 100 | 101 | ### Installing JZMQ 102 | 103 | {% highlight sh %} 104 | cd ~/src 105 | git clone https://github.com/nathanmarz/jzmq.git 106 | cd jzmq 107 | ./autogen.sh 108 | ./configure 109 | make 110 | sudo make install 111 | {% endhighlight %} 112 | 113 | ### Installing Storm 114 | 115 | {% highlight sh %} 116 | cd ~/src 117 | wget https://github.com/downloads/nathanmarz/storm/storm-0.7.0.zip 118 | unzip storm-0.7.0.zip 119 | {% endhighlight %} 120 | 121 | ## Configuring Storm 122 | 123 | We need to point storm to the correct zookeeper servers, as well as [setup other config options](https://github.com/nathanmarz/storm/wiki/Setting-up-a-Storm-cluster). For now, we'll just modify the `conf/storm.yaml` file to look like this: 124 | 125 | {% highlight yaml %} 126 | storm.local.dir: "/tmp/storm" 127 | storm.zookeeper.servers: 128 | - "zookeeper" 129 | nimbus.host: "localhost" 130 | {% endhighlight %} 131 | 132 | You'll want to put some real values in there depending on the size of your cluster, and you'll definitely want to change `/tmp/storm` to something more persistent, but this sufices for a demo. 133 | 134 | ## Running Storm 135 | 136 | In order to run storm, you need both nimbus and supervisor processes running. We can run them with `nohup`: 137 | 138 | {% highlight sh %} 139 | nohup ~/src/storm-0.7.0/bin/storm nimbus & 140 | nohup ~/src/storm-0.7.0/bin/storm supervisor & 141 | {% endhighlight %} 142 | 143 | Now it should be ready to process topologies! 144 | 145 | ## Running the Storm UI 146 | 147 | Storm comes with a nifty dashboard to view cluster stats. To run it, just do: 148 | 149 | {% highlight sh %} 150 | nohup ~/src/storm-0.7.0/bin/storm ui & 151 | {% endhighlight %} 152 |
153 | -------------------------------------------------------------------------------- /javascripts/sidebar.js: -------------------------------------------------------------------------------- 1 | var tutorials, visible, visible_counts, hidden, dict, filters = []; 2 | 3 | $(function() { 4 | // Grab all tutorials 5 | tutorials = $("div.tutorial"); 6 | 7 | // Mark all tutorials as visible 8 | tutorials.show(); 9 | 10 | // Render license/source information 11 | _(tutorials).each(function(tutorial){ 12 | t = $(tutorial); 13 | d = t.data(); 14 | var meta = d.authorGithub || d.author || d.source || d.license; 15 | if(meta) { 16 | var attribution = ""; 17 | if(d.authorGithub) { 18 | attribution += 'by ' + d.authorGithub + ''; 19 | } else if(d.author) { 20 | attribution += "by " + d.author + "" 21 | } 22 | if(d.source) { 23 | if (d.authorGithub || d.author) { 24 | attribution += '|'; 25 | } 26 | attribution += 'Original Source'; 27 | } 28 | if(d.license) { 29 | if (d.authorGithub || d.author || d.source) { 30 | attribution += '|'; 31 | } 32 | attribution += 'License'; 33 | } 34 | t.prepend("

" + attribution + "

"); 35 | } 36 | }); 37 | 38 | dict = _.chain(tutorials) 39 | .reduce(function(lookup, tutorial) { 40 | _($(tutorial).data().facets).each(function(val, key) { 41 | if(!_(lookup).has(key)) { lookup[key] = {}; } 42 | // We want to be able to have multiple values for vertain 43 | // facets, so we convert strings to arrays and iterate over each 44 | if(_(val).isString()) { val = [val]; } 45 | _(val).each(function(v) { 46 | if(!_(lookup[key]).has(v)) { lookup[key][v] = []; } 47 | lookup[key][v].push(tutorial); 48 | }); 49 | }); 50 | return lookup; 51 | }, {}) 52 | .value(); 53 | 54 | // Draw the sidebar 55 | redraw(); 56 | 57 | //Fix sidebar 58 | function sidebar_fix() { 59 | var header_height = $('header').height(), 60 | footer_height = 150, //fixed 61 | window_height = $(window).height(), 62 | $nav_sidebar = $('nav#sidebar'), 63 | sidebar_height= $nav_sidebar.height(), 64 | difference = window_height - (header_height + footer_height); 65 | 66 | if ($(window).width()>970){ 67 | var existence = sidebar_height+difference; 68 | $('header h1').css('paddingTop', 0); 69 | if (existence>250) { 70 | $nav_sidebar.height(existence); 71 | if ($('header').width()==250) { 72 | $('header').css('position', 'fixed'); 73 | $('footer').css('position', 'fixed'); 74 | } 75 | } 76 | } else { 77 | $nav_sidebar.css('height', 'auto'); 78 | $('header').css('position', 'static'); 79 | $('footer').css('position', 'static'); 80 | $('header h1').css('paddingTop', $('section#main h1').height()); 81 | } 82 | 83 | } 84 | sidebar_fix(); 85 | $(window).resize(function() { sidebar_fix() }); 86 | 87 | // title fix 88 | var $section = $('section#main'), 89 | $title = $section.find('h1'), 90 | title_height = $title.height(), 91 | set_padding = title_height + 20; 92 | $section.css('paddingTop',set_padding); 93 | 94 | // Hide tutorials if the user clicks on a facet 95 | $("nav li").live("click", function(e) { 96 | target = $(this).data(); 97 | existing_filter = _(filters).find(function(filter) { 98 | return filter.name === target.name && filter.value === target.value; 99 | }); 100 | if(existing_filter) { 101 | _gaq.push(['_trackEvent', 'filters - remove', existing_filter.name, existing_filter.value, filters.size]); 102 | filters = _(filters).without(existing_filter); 103 | } else { 104 | _gaq.push(['_trackEvent', 'filters - apply', target.name, target.value, filters.size]); 105 | filters = _(filters).reject(function(filter) { return filter.name === target.name && filter.value === target.value; }); 106 | filters.push(target); 107 | } 108 | redraw(); 109 | }); 110 | }); 111 | 112 | function redraw() { 113 | update_visibility(); 114 | update_sidebar(); 115 | var template = $("#sidebar_template").text(); 116 | var list = _.template(template); 117 | $("#sidebar").html(list); 118 | }; 119 | 120 | function update_visibility() { 121 | // Grab all the tutorials for each facet into an array 122 | all = _.chain(filters).map(function(filter) { 123 | return dict[filter.name][filter.value]; 124 | }).flatten().value(); 125 | 126 | // Only keep the tutorials that are visible 127 | keep = _(tutorials).select(function(tutorial) { 128 | return all.length - _(all).without(tutorial).length === filters.length 129 | }); 130 | 131 | // Make DOM elements visible or not 132 | $(keep).show(); 133 | $(_(tutorials).difference(keep)).hide(); 134 | }; 135 | 136 | function update_sidebar() { 137 | visible = _.chain($("div.tutorial:visible")) 138 | // Collect all the facets 139 | .map(function(tutorial) { return $(tutorial).data().facets; }) 140 | // and combine all facets into a nested hash 141 | .reduce(function(counts, facets) { 142 | // by iterating over each pair and aggregating the counts of each 143 | _(facets).each(function(val, key) { 144 | // Initialize the names 145 | if(!_(counts).has(key)) { counts[key] = {}; } 146 | // and the values/counts 147 | if(_(val).isString()) { val = [val]; } 148 | _(val).each(function(v) { 149 | if(!_(counts[key]).has(v)) { counts[key][v] = 0; } 150 | // then increment the counts 151 | counts[key][v] += 1; 152 | }); 153 | }); 154 | return counts; 155 | // This is where we're storing the new data 156 | }, {}) 157 | // Get the final counts 158 | .value(); 159 | 160 | // Generate counts for the sidebar 161 | var counts = {}; 162 | _(visible).each(function(val, key) { 163 | counts[key] = _(val).keys().length; 164 | }); 165 | visible_counts = counts; 166 | }; 167 | -------------------------------------------------------------------------------- /pages/retrieving-storm-data-from-nimbus.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Retrieving Storm Cluster Statistics from Nimbus 4 | --- 5 | 6 | # Retrieving Storm Cluster Statistics from Nimbus 7 | 8 | This tutorial will show how to obtain basic storm topology statistics from nimbus (similar to the information show in the storm ui dashboard) so you can store that data in a separate location -- such as graphite -- for monitoring. Since storm topologies are thrift-based, you can use almost any language to connect to nimbus to download your data. 9 | 10 |
16 | 17 | ## Assumptions 18 | 19 | We assume you'll store your data in `~/code`. We also assume that your homebrew is newer enough that the `/usr/local` directory is homebrew's git repo. 20 | 21 | ## Setup 22 | 23 | Let's make a location to store our project: 24 | 25 | {% highlight sh %} 26 | mkdir -p ~/code/nimbus-thrift-demo 27 | {% endhighlight %} 28 | 29 | ## Download the Storm Source Code 30 | 31 | In order to connect to nimbus, we need to get the `storm.thrift` file from the storm source, and use that to generate the thrift bindings in ruby: 32 | 33 | {% highlight sh %} 34 | cd ~/code 35 | wget https://github.com/downloads/nathanmarz/storm/storm-0.7.0.zip 36 | unzip storm-0.7.0.zip 37 | {% endhighlight %} 38 | 39 | ## Install Thrift 0.7.0 and the Thrift Gem 40 | 41 | Now let's install the same version of thrift that storm 0.7.0 uses: 42 | 43 | {% highlight sh %} 44 | cd /usr/local 45 | brew update 46 | brew versions thrift 47 | git checkout 141ddb6 /usr/local/Library/Formula/thrift.rb 48 | brew install thrift 49 | {% endhighlight %} 50 | 51 | And the thrift gem: 52 | 53 | {% highlight sh %} 54 | gem install thrift 55 | {% endhighlight %} 56 | 57 | ## Generate the Ruby Bindings 58 | 59 | {% highlight sh %} 60 | cd ~/code/nimbus-thrift-demo 61 | cp ~/code/storm-0.7.0/src/storm.thrift . 62 | thrift --gen rb storm.thrift 63 | {% endhighlight %} 64 | 65 | ## Connect to Nimbus 66 | 67 | Now that we have the ruby bindings in place, we can create a sample app to connect to our nimbus cluster. Copy the following to `test.rb`, replacing `localhost` with the hostname of your nimbus instance: 68 | 69 | {% highlight ruby %} 70 | $:.push('gen-rb') 71 | 72 | require 'rubygems' 73 | require 'thrift' 74 | require 'nimbus' 75 | 76 | begin 77 | socket = Thrift::Socket.new('localhost', 6627) 78 | transport = Thrift::FramedTransport.new(socket) 79 | protocol = Thrift::BinaryProtocol.new(transport) 80 | client = Nimbus::Client.new(protocol) 81 | 82 | transport.open 83 | 84 | summary = client.getClusterInfo 85 | puts summary.inspect 86 | 87 | transport.close 88 | 89 | rescue Thrift::Exception => tx 90 | print 'Thrift::Exception: ', tx.message, "\n" 91 | end 92 | {% endhighlight %} 93 | 94 | Now we can run our test app: 95 | 96 | {% highlight sh %} 97 | ruby test.rb 98 | {% endhighlight %} 99 | 100 | Now you can take that data and write it to where you'd like. Enjoy! 101 |
102 |
103 | 104 |
110 | 111 | ## Assumptions 112 | 113 | We assume you'll store your data in `~/code`. 114 | 115 | ## Setup 116 | 117 | Let's make a location to store our project: 118 | 119 | {% highlight sh %} 120 | mkdir -p ~/code/nimbus-thrift-demo 121 | {% endhighlight %} 122 | 123 | ## Download the Storm Source Code 124 | 125 | In order to connect to nimbus, we need to get the `storm.thrift` file from the storm source, and use that to generate the thrift bindings in python: 126 | 127 | {% highlight sh %} 128 | cd ~/code 129 | wget https://github.com/downloads/nathanmarz/storm/storm-0.7.0.zip 130 | unzip storm-0.7.0.zip 131 | {% endhighlight %} 132 | 133 | ## Install Thrift 0.7.0 and the Thrift Python Package 134 | 135 | Now let's install the same version of thrift that storm 0.7.0 uses: 136 | 137 | {% highlight sh %} 138 | cd /usr/local 139 | brew update 140 | brew versions thrift 141 | git checkout 141ddb6 /usr/local/Library/Formula/thrift.rb 142 | brew install thrift 143 | {% endhighlight %} 144 | 145 | And the thrift python package: 146 | 147 | {% highlight sh %} 148 | pip install thrift==0.7.0 149 | {% endhighlight %} 150 | 151 | ## Generate the Python Bindings 152 | 153 | {% highlight sh %} 154 | cd ~/code/nimbus-thrift-demo 155 | cp ~/code/storm-0.7.0/src/storm.thrift . 156 | thrift --gen py storm.thrift 157 | {% endhighlight %} 158 | 159 | ## Connect to Nimbus 160 | 161 | Now that we have the python bindings in place, we can create a sample app to connect to our nimbus cluster. Copy the following to `test.py`, replacing `localhost` with the hostname of your nimbus instance: 162 | 163 | {% highlight python %} 164 | import sys 165 | 166 | sys.path.append('gen-py') 167 | 168 | from thrift import Thrift 169 | from thrift.transport import TSocket 170 | from thrift.transport import TTransport 171 | from thrift.protocol import TBinaryProtocol 172 | 173 | from storm import Nimbus 174 | from storm.ttypes import * 175 | from storm.constants import * 176 | 177 | try: 178 | socket = TSocket.TSocket('localhost', 6627) 179 | transport = TTransport.TFramedTransport(socket) 180 | protocol = TBinaryProtocol.TBinaryProtocol(transport) 181 | client = Nimbus.Client(protocol) 182 | 183 | transport.open() 184 | 185 | summary = client.getClusterInfo() 186 | print summary 187 | 188 | transport.close() 189 | 190 | except Thrift.TException, tx: 191 | print "%s" % (tx.message) 192 | {% endhighlight %} 193 | 194 | Now we can run our test app: 195 | 196 | {% highlight sh %} 197 | python test.py 198 | {% endhighlight %} 199 | 200 | Now you can take that data and write it to where you'd like. Enjoy! 201 |
202 |
203 | -------------------------------------------------------------------------------- /stylesheets/styles.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Lato:300italic,700italic,300,700); 2 | 3 | body { 4 | font:14px/1.5 Lato, "Helvetica Neue", Helvetica, Arial, sans-serif; 5 | color:#777; 6 | font-weight:300; 7 | margin:0px; 8 | padding:0px; 9 | } 10 | 11 | h1, h2, h3, h4, h5, h6 { 12 | color:#222; 13 | margin:0 0 20px; 14 | } 15 | 16 | p, ul, ol, table, pre, dl { 17 | margin:0 0 20px; 18 | } 19 | 20 | h1, h2, h3 { 21 | line-height:1.1; 22 | } 23 | 24 | h1 { 25 | font-size:28px; 26 | } 27 | 28 | h2 { 29 | color:#393939; 30 | } 31 | 32 | h3, h4, h5, h6 { 33 | color:#494949; 34 | } 35 | 36 | a { 37 | color:#39c; 38 | font-weight:400; 39 | text-decoration:none; 40 | } 41 | 42 | a small { 43 | font-size:11px; 44 | color:#777; 45 | margin-top:-0.6em; 46 | display:block; 47 | } 48 | 49 | .wrapper { 50 | width:860px; 51 | margin:0 auto; 52 | } 53 | 54 | blockquote { 55 | border-left:1px solid #e5e5e5; 56 | margin:0; 57 | padding:0 0 0 20px; 58 | font-style:italic; 59 | } 60 | 61 | code, pre { 62 | font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; 63 | color:#333; 64 | font-size:12px; 65 | } 66 | 67 | pre { 68 | padding:8px 15px; 69 | background: #f8f8f8; 70 | border-radius:5px; 71 | border:1px solid #e5e5e5; 72 | overflow-x: auto; 73 | } 74 | 75 | table { 76 | width:100%; 77 | border-collapse:collapse; 78 | } 79 | 80 | th, td { 81 | text-align:left; 82 | padding:5px 10px; 83 | border-bottom:1px solid #e5e5e5; 84 | } 85 | 86 | dt { 87 | color:#444; 88 | font-weight:700; 89 | } 90 | 91 | th { 92 | color:#444; 93 | } 94 | 95 | img { 96 | max-width:100%; 97 | } 98 | 99 | header { 100 | width:250px; 101 | float:left; 102 | position:fixed; 103 | z-index:2; 104 | background:#fff; 105 | -moz-box-shadow: 0px 5px 10px #FFF; 106 | -webkit-box-shadow: 0px 5px 10px #FFF; 107 | box-shadow: 0px 5px 10px #FFF; 108 | padding-top:10px; 109 | } 110 | strong { 111 | color:#222; 112 | font-weight:700; 113 | } 114 | 115 | #sidebar{ 116 | overflow-y: scroll; 117 | height: 400px; 118 | } 119 | 120 | #sidebar ul h3 { 121 | margin: 0; 122 | } 123 | 124 | #sidebar ul, #main div.tutorial ul { 125 | list-style:none; 126 | margin-left:0; 127 | padding:0; 128 | } 129 | 130 | #sidebar ul li{ 131 | cursor:pointer; 132 | color:#39C; 133 | } 134 | 135 | #sidebar ul li:hover{ 136 | cursor:pointer; 137 | color:#2c85b1; 138 | text-decoration:none; 139 | } 140 | 141 | .headroom{ 142 | margin: 20px 0 0 0; 143 | } 144 | 145 | .less_headroom{ 146 | margin: 10px 0 0 0; 147 | } 148 | 149 | .footroom{ 150 | margin: 0 0 20px; 151 | } 152 | 153 | .less_footroom{ 154 | margin: 0 0 10px; 155 | } 156 | 157 | .line_bottom{ 158 | border-bottom: 1px dotted #ccc; 159 | margin-bottom:10px; 160 | } 161 | 162 | div.social a.ftg{ 163 | width:79px; 164 | } 165 | 166 | div.tutorial p.about span{ 167 | margin-right:5px; 168 | } 169 | 170 | section#main { 171 | width:580px; 172 | float:right; 173 | padding:50px 0; 174 | } 175 | 176 | section#main h1{ 177 | position:fixed; 178 | top:0px; 179 | z-index:1; 180 | width: 580px; 181 | padding: 10px 0; 182 | -moz-box-shadow: 0px 5px 10px #FFF; 183 | -webkit-box-shadow: 0px 5px 10px #FFF; 184 | box-shadow: 0px 5px 10px #FFF; 185 | background:#FFF; 186 | } 187 | 188 | a.ribbon img.fork { 189 | position: fixed; 190 | top: 0; 191 | right: 0; 192 | border: 0; 193 | z-index:3; 194 | } 195 | 196 | small { 197 | font-size:11px; 198 | } 199 | 200 | hr { 201 | border:0; 202 | background:#aaa; 203 | height:1px; 204 | margin:0 0 20px; 205 | } 206 | 207 | footer { 208 | width:250px; 209 | float:left; 210 | bottom:10px; 211 | position:fixed; 212 | z-index:1; 213 | } 214 | 215 | a.hidden_ribbon{ 216 | display:none; 217 | border-top:1px dotted #CCC; 218 | margin-top:10px; 219 | } 220 | 221 | @media print, screen and (max-width: 960px) { 222 | body { 223 | padding:15px; 224 | } 225 | div.wrapper { 226 | width:auto; 227 | margin:0; 228 | } 229 | header, section#main, footer { 230 | float:none; 231 | position:static; 232 | width:auto; 233 | } 234 | header { 235 | width:100%; 236 | } 237 | a.ribbon img.fork { 238 | display:none; 239 | } 240 | a.hidden_ribbon{ 241 | display:block; 242 | } 243 | section#main { 244 | border:1px solid #e5e5e5; 245 | border-width:1px 0; 246 | padding:20px 0; 247 | margin:0 0 20px; 248 | width:100%; 249 | } 250 | section#main h1{ 251 | width:100%; 252 | } 253 | header a small { 254 | display:inline; 255 | } 256 | #sidebar ul li{ 257 | float:left; 258 | } 259 | #sidebar ul li span.count{ 260 | display:none; 261 | } 262 | #sidebar ul li:after{ 263 | margin-right:5px; 264 | content:"|"; 265 | } 266 | #sidebar ul li:last-child:after{ 267 | content:""; 268 | } 269 | #sidebar ul { 270 | *zoom: 1; 271 | } 272 | #sidebar ul:before, #sidebar ul:after { 273 | display: table; 274 | content: ""; 275 | } 276 | #sidebar ul:after { 277 | clear: both; 278 | } 279 | } 280 | 281 | @media print, screen and (max-width: 720px) { 282 | body { 283 | word-wrap:break-word; 284 | padding:15px; 285 | } 286 | header { 287 | padding:0; 288 | width:100%; 289 | } 290 | header p.view { 291 | position:static; 292 | } 293 | section#main{ 294 | float:left; 295 | width:100%; 296 | } 297 | section#main h1{ 298 | width:100%; 299 | } 300 | a.ribbon img.fork { 301 | display:none; 302 | } 303 | a.hidden_ribbon{ 304 | display:block; 305 | } 306 | #sidebar ul li{ 307 | float:left; 308 | } 309 | #sidebar ul li span.count{ 310 | display:none; 311 | } 312 | #sidebar ul li:after{ 313 | margin-right:5px; 314 | content:"|"; 315 | } 316 | #sidebar ul li:last-child:after{ 317 | content:""; 318 | } 319 | #sidebar ul { 320 | *zoom: 1; 321 | } 322 | #sidebar ul:before, #sidebar ul:after { 323 | display: table; 324 | content: ""; 325 | } 326 | #sidebar ul:after { 327 | clear: both; 328 | } 329 | } 330 | 331 | @media print, screen and (max-width: 480px) { 332 | body { 333 | padding:15px; 334 | } 335 | a.ribbon img.fork { 336 | display:none; 337 | } 338 | a.hidden_ribbon{ 339 | display:block; 340 | } 341 | section#main{ 342 | float:left; 343 | width:100%; 344 | } 345 | section#main h1{ 346 | width:100%; 347 | } 348 | header{ 349 | padding:0; 350 | width:100%; 351 | } 352 | #sidebar ul li{ 353 | float:left; 354 | } 355 | #sidebar ul li span.count{ 356 | display:none; 357 | } 358 | #sidebar ul li:after{ 359 | margin-right:5px; 360 | content:"|"; 361 | } 362 | #sidebar ul li:last-child:after{ 363 | content:""; 364 | } 365 | #sidebar ul { 366 | *zoom: 1; 367 | } 368 | #sidebar ul:before, #sidebar ul:after { 369 | display: table; 370 | content: ""; 371 | } 372 | #sidebar ul:after { 373 | clear: both; 374 | } 375 | 376 | } 377 | 378 | @media print { 379 | body { 380 | padding:0.4in; 381 | font-size:12pt; 382 | color:#444; 383 | } 384 | section#main{ 385 | border:0px none; 386 | } 387 | header h1{ 388 | visibility: hidden; 389 | } 390 | footer{ 391 | display:none; 392 | } 393 | } 394 | -------------------------------------------------------------------------------- /pages/installing-mysql.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Installing MySQL 4 | --- 5 | 6 | Installing MySQL 7 | ================ 8 | 9 |
16 | To install MySQL, run the following command from a terminal prompt: 17 | 18 | {% highlight sh %} 19 | sudo apt-get install mysql-server 20 | {% endhighlight %} 21 | 22 | During the installation process you will be prompted to enter a password for the __MySQL__ root user. 23 | 24 | Once the installation is complete, the MySQL server should be started automatically. You can run the following command from a terminal prompt to check whether the MySQL server is running: 25 | 26 | {% highlight sh %} 27 | sudo netstat -tap | grep mysql 28 | {% endhighlight %} 29 | 30 | When you run this command, you should see the following line or something similar: 31 | 32 | {% highlight sh %} 33 | tcp 0 0 localhost.localdomain:mysql *:* LISTEN - 34 | {% endhighlight %} 35 | 36 | If the server is not running correctly, you can type the following command to start it: 37 | 38 | {% highlight sh %} 39 | sudo /etc/init.d/mysql restart 40 | {% endhighlight %} 41 | 42 | Configuration 43 | ------------- 44 | You can edit the `/etc/mysql/my.cnf` file to configure the basic settings -- log file, port number, etc. For example, to configure __MySQL__ to listen for connections from network hosts, change the `bind_address` directive to the server's IP address: 45 | 46 | {% highlight sh %} 47 | bind-address = 192.168.0.5 48 | {% endhighlight %} 49 | 50 | Note Replace 192.168.0.5 with the appropriate address. 51 | 52 | After making a change to `/etc/mysql/my.cnf` the __mysql__ daemon will need to be restarted: 53 | 54 | {% highlight sh %} 55 | sudo /etc/init.d/mysql restart 56 | {% endhighlight %} 57 | 58 | --------------------------------------------------------- 59 | 60 |
61 | 62 |
68 | These are instructions for compiling and installing a 64-bit version of [MySQL](http://www.mysql.com/), the world's most popular open source database, on Mac OS X 10.6 (Snow Leopard). 69 | 70 | The benefits of manually building MySQL yourself in `/usr/local` are detailed [here](http://hivelogic.com/articles/using_usr_local/). I also wrote a in-depth explanation of why you might want to build MySQL yourself in my [Compiling MySQL on Leopard](http://hivelogic.com/articles/installing-mysql-on-mac-os-x/) article. 71 | 72 | NO SUPPORT 73 | ---------- 74 | These instructions will probably work just fine and you won't run into any trouble, but if you do, **please don't email me about it**. I wish I could help everybody who might have an issue, but I just don't have the time to help you troubleshoot hundreds of potential variables with your specific configuration, and I probably won't even reply to the email, and I'm sorry in advance for that. 75 | 76 | PREREQUISITES 77 | ------------- 78 | Before following these instructions, you will need: 79 | 80 | - Mac OS X 10.6 Snow Leopard 81 | - The latest Xcode Tools (from the Snow Leopard DVD or downloaded from [Apple](http://developer.apple.com/) - the 10.5 version _won't work_) 82 | - Confidence running UNIX commands using the Terminal 83 | 84 | If you want to learn more about UNIX and the command line, check out [my PeepCode screencast](http://peepcode.com/products/meet-the-command-line) on this topic. 85 | 86 | STEP 1: SET THE PATH 87 | -------------------- 88 | Launch Terminal.app from the `/Applications/Utilities` folder. 89 | 90 | We need to set your shell's `PATH` variable first. The `PATH` variable determines where your system searches for command-line programs. Using the editor of your choice, create and edit a file in your home directory named `.profile` (note the "." preceding the filename). 91 | 92 | If you're using [TextMate](http://macromates.com/) like you should be and have [installed the UNIX `mate` command](http://manual.macromates.com/en/using_textmate_from_terminal.html), then you can create and start editing the file like this: 93 | 94 | {% highlight sh %} 95 | mate ~/.profile 96 | {% endhighlight %} 97 | 98 | To the end of this file, add the following line (or verify that it's already there): 99 | 100 | {% highlight sh %} 101 | export PATH="/usr/local/bin:/usr/local/sbin:/usr/local/mysql/bin:$PATH" 102 | {% endhighlight %} 103 | 104 | Close and save the file and run this command to load the new setting into your current shell: 105 | 106 | source ~/.profile 107 | To verify that you've updated your path, enter the following command: 108 | 109 | {% highlight sh %} 110 | echo $PATH 111 | {% endhighlight %} 112 | 113 | You should see `/usr/local/bin` at the beginning of the line returned by the system. 114 | 115 | STEP 2: DOWNLOAD 116 | ---------------- 117 | 118 | We're going to create a folder to contain the files we're about to download and compile. If you want, you can delete this folder when you're done, but keeping it around makes it easier to re-install (or uninstall) these apps later. 119 | 120 | Make the new folder: 121 | 122 | {% highlight sh %} 123 | mkdir ~/src 124 | cd ~/src 125 | {% endhighlight %} 126 | 127 | I used to provide a link to download the latest version of MySQL, but they update frequently and sometimes the links die, so instead, please go to the MySQL site, and download the latest version from [this page](http://dev.mysql.com/get/Downloads/MySQL-5.1/mysql-5.1.39.tar.gz/from/pick#mirrors), picking a mirror near you. Then move or copy it to your `src` folder. 128 | 129 | For those of you who expect the world, you can try this command, but please don't email me if it's broken: 130 | 131 | {% highlight sh %} 132 | curl -O http://mysql.mirrors.pair.com/Downloads/MySQL-5.1/mysql-5.1.39.tar.gz 133 | {% endhighlight %} 134 | 135 | STEP 3: COMPILE AND INSTALL 136 | --------------------------- 137 | 138 | Build and install MySQL like this: 139 | 140 | {% highlight sh %} 141 | tar xzvf mysql-5.1.37.tar.gz 142 | cd mysql-5.1.37 143 | ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --enable-shared --with-plugins=innobase 144 | make 145 | sudo make install 146 | cd /usr/local/mysql 147 | sudo ./bin/mysql_install_db --user=mysql 148 | sudo chown -R mysql ./var 149 | cd .. 150 | {% endhighlight %} 151 | 152 | STARTING (AND AUTO-STARTING) MYSQL 153 | ---------------------------------- 154 | 155 | In most cases, you'll want MySQL to auto-start every time you boot (or reboot) your Mac. The easiest way to do this is using launchd, Mac OS X's infrastructure for managing system processes. 156 | 157 | I've prepared a launchd plist file that will allow you to manage MySQL, starting it at boot and stopping it cleanly at shutdown. Save the plist file to your `~/src` directory and then move it to the proper place with the following commands: 158 | 159 | {% highlight sh %} 160 | cd ~/src 161 | curl -O http://hivelogic.com/downloads/com.mysql.mysqld.plist 162 | sudo mv ~/src/com.mysql.mysqld.plist /Library/LaunchDaemons 163 | sudo chown root /Library/LaunchDaemons/com.mysql.mysqld.plist 164 | {% endhighlight %} 165 | 166 | Finally, tell `launchd` to load and startup MySQL: 167 | 168 | {% highlight sh %} 169 | sudo launchctl load -w /Library/LaunchDaemons/com.mysql.mysqld.plist 170 | {% endhighlight %} 171 | 172 | If you see no response, it probably means that everything worked correctly, and that MySQL is running. You can verify this by launching MySQL's command-line monitor: 173 | 174 | {% highlight sh %} 175 | mysql -uroot 176 | {% endhighlight %} 177 | 178 | You should see something like this: 179 | 180 | {% highlight sh %} 181 | Welcome to the MySQL monitor. Commands end with ; or g. 182 | Your MySQL connection id is 1 183 | Server version: 5.1.37 Source distribution 184 | Type 'help;' or 'h' for help. Type 'c' to clear the buffer. 185 | mysql> 186 | {% endhighlight %} 187 | 188 | If this prompt appears, MySQL has been installed correctly. Type `exit` and press return to quit the MySQL monitor. 189 | 190 | If you didn't see that message, it's possible that something "bad" happened, or that you may have missed a step above. You can always try running through the instructions again. 191 | 192 | You now have a custom-built 64-bit version of MySQL. 193 | 194 | STARTING AND STOPPING MYSQL MANUALLY 195 | ------------------------------------ 196 | 197 | If you ever want to stop MySQL manually, use this command: 198 | 199 | {% highlight sh %} 200 | sudo launchctl unload -w /Library/LaunchDaemons/com.mysql.mysqld.plist 201 | {% endhighlight %} 202 | 203 | To (re)start MySQL manually, use this command: 204 | 205 | {% highlight sh %} 206 | sudo launchctl load -w /Library/LaunchDaemons/com.mysql.mysqld.plist 207 | {% endhighlight %} 208 | 209 | EXTRA CREDIT: THE RAILS GEM 210 | --------------------------- 211 | 212 | You can install the Rails MySQL Gem by pointing it at your new MySQL installation direcory: 213 | 214 | {% highlight sh %} 215 | sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql 216 | {% endhighlight %} 217 | 218 | That should do it. 219 | 220 | --------------------------------------------------------- 221 | 222 |
223 | 224 |
230 | If you already have a `/usr/local` folder and it's not owned by your user: 231 | 232 | {% highlight sh %} 233 | sudo chown -R `whoami` /usr/local 234 | {% endhighlight %} 235 | 236 | Install Homebrew: 237 | 238 | {% highlight sh %} 239 | cd /usr/local 240 | git init 241 | git remote add origin git://github.com/mxcl/homebrew.git 242 | git pull origin master 243 | {% endhighlight %} 244 | 245 | This is kind of odd -- you install Homebrew right into the base of your `/usr/local` folder. It nicely ignores other folders that already exists there. Just do it. 246 | 247 | Install MySQL: 248 | 249 | {% highlight sh %} 250 | brew install mysql 251 | {% endhighlight %} 252 | 253 | Yeah, it's really that easy. This will take a while. 254 | 255 | Now warm it up: 256 | 257 | {% highlight sh %} 258 | mysql_install_db 259 | {% endhighlight %} 260 | 261 | And make sure it automatically starts again on login: 262 | 263 | {% highlight sh %} 264 | launchctl load -w /usr/local/Cellar/mysql/5.1.43/com.mysql.mysqld.plist 265 | {% endhighlight %} 266 | 267 | --------------------------------------------------------- 268 | 269 |
270 | -------------------------------------------------------------------------------- /pages/hello-world.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Hello, World! 4 | --- 5 | 6 | Hello, World! 7 | ============= 8 | 9 | Here are some examples of "Hello, World!" in various programming languages. 10 | 11 |
12 | ActionScript 13 | ------------ 14 | 15 | {% highlight as %} 16 | trace("Hello, World!"); 17 | {% endhighlight %} 18 |
19 | 20 |
21 | Ada 22 | --- 23 | 24 | {% highlight ada %} 25 | with TEXT_IO; 26 | 27 | procedure HELLO is 28 | begin 29 | TEXT_IO.PUT_LINE ("Hello, World!"); 30 | end HELLO; 31 | {% endhighlight %} 32 |
33 | 34 |
35 | AppleScript 36 | ----------- 37 | 38 | {% highlight applescript %} 39 | return "Hello, World!" 40 | {% endhighlight %} 41 |
42 | 43 |
44 | Awk 45 | --- 46 | 47 | {% highlight awk %} 48 | BEGIN { print "Hello, World!" } 49 | {% endhighlight %} 50 |
51 | 52 |
53 | Befunge 54 | ------- 55 | 56 | {% highlight befunge %} 57 | > v 58 | v ,,,,,"Hello"< 59 | >48*, v 60 | v,,,,,,"World!"< 61 | >25*,@ 62 | {% endhighlight %} 63 |
64 | 65 |
66 | Boo 67 | --- 68 | 69 | {% highlight boo %} 70 | print "Hello, World!" 71 | {% endhighlight %} 72 |
73 | 74 |
75 | BrainFuck 76 | --------- 77 | 78 | {% highlight bf %} 79 | ++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>. 80 | {% endhighlight %} 81 |
82 | 83 |
84 | C 85 | - 86 | 87 | {% highlight c %} 88 | #include 89 | 90 | int main(void) 91 | { 92 | printf("Hello, World!"); 93 | return 0; 94 | } 95 | {% endhighlight %} 96 |
97 | 98 |
99 | C++ 100 | --- 101 | 102 | {% highlight cpp %} 103 | #include 104 | 105 | int main() 106 | { 107 | std::cout << "Hello, World!\n"; 108 | } 109 | {% endhighlight %} 110 |
111 | 112 |
113 | C# 114 | -- 115 | 116 | {% highlight csharp %} 117 | using System; 118 | 119 | class HelloWorld 120 | { 121 | static void Main() 122 | { 123 | System.Console.WriteLine("Hello, World!"); 124 | } 125 | } 126 | {% endhighlight %} 127 |
128 | 129 |
130 | Clojure 131 | ------- 132 | 133 | {% highlight clj %} 134 | (def hello (fn [] "Hello, World!")) 135 | (hello) 136 | {% endhighlight %} 137 |
138 | 139 |
140 | CoffeeScript 141 | ------------ 142 | 143 | {% highlight coffeescript %} 144 | alert "Hello, World!" 145 | {% endhighlight %} 146 |
147 | 148 |
149 | ColdFusion 150 | ---------- 151 | 152 | {% highlight cfm %} 153 | Hello, World! 154 | {% endhighlight %} 155 |
156 | 157 |
158 | Common Lisp 159 | ----------- 160 | 161 | {% highlight cl %} 162 | (format t "Hello, World!~%") 163 | {% endhighlight %} 164 | 165 | or 166 | 167 | {% highlight cl %} 168 | (write-line "Hello World!") 169 | {% endhighlight %} 170 | 171 | or 172 | 173 | {% highlight cl %} 174 | "Hello World!" 175 | {% endhighlight %} 176 | 177 |
178 | 179 |
180 | Cython 181 | ------ 182 | 183 | {% highlight pyx %} 184 | print "Hello, World!" 185 | {% endhighlight %} 186 |
187 | 188 |
189 | D 190 | - 191 | 192 | {% highlight d %} 193 | import std.stdio; 194 | 195 | void main () 196 | { 197 | writef("Hello, World!"); 198 | } 199 | {% endhighlight %} 200 |
201 | 202 |
203 | Dart 204 | ---- 205 | 206 | {% highlight dart %} 207 | main() 208 | { 209 | print('Hello, World!'); 210 | } 211 | {% endhighlight %} 212 |
213 | 214 |
215 | Delphi 216 | ------ 217 | 218 | {% highlight delphi %} 219 | program Hello_World; 220 | uses 221 | Windows; 222 | 223 | begin 224 | ShowMessage("Hello, World!"); 225 | end. 226 | {% endhighlight %} 227 |
228 | 229 |
230 | Dylan 231 | ----- 232 | 233 | {% highlight dylan %} 234 | module: hello 235 | 236 | format-out("Hello, World!\n"); 237 | {% endhighlight %} 238 |
239 | 240 |
241 | Erlang 242 | ------ 243 | 244 | {% highlight erlang %} 245 | -module(hello). 246 | -export([hello_world/0]). 247 | 248 | hello_world() -> io:fwrite("Hello, World!\n"). 249 | {% endhighlight %} 250 |
251 | 252 |
253 | Factor 254 | ------ 255 | 256 | {% highlight factor %} 257 | "Hello, World!" print 258 | {% endhighlight %} 259 |
260 | 261 |
262 | Fancy 263 | ----- 264 | 265 | {% highlight fy %} 266 | "Hello, World!" println 267 | {% endhighlight %} 268 |
269 | 270 |
271 | F# 272 | -- 273 | 274 | {% highlight fsharp %} 275 | print_endline "Hello, World!" 276 | {% endhighlight %} 277 |
278 | 279 |
280 | Fortran 281 | ------- 282 | 283 | {% highlight fortran %} 284 | PROGRAM HELLO 285 | PRINT *, 'Hello, World!' 286 | END 287 | {% endhighlight %} 288 |
289 | 290 |
291 | Groovy 292 | ------ 293 | 294 | {% highlight groovy %} 295 | println "Hello, World" 296 | {% endhighlight %} 297 |
298 | 299 |
300 | Haskell 301 | ------- 302 | 303 | {% highlight hs %} 304 | module Main (main) where 305 | 306 | main = putStrLn "Hello, World!" 307 | {% endhighlight %} 308 |
309 | 310 |
311 | Io 312 | -- 313 | 314 | {% highlight io %} 315 | write("Hello, World!\n") 316 | {% endhighlight %} 317 |
318 | 319 |
320 | Java 321 | ---- 322 | 323 | {% highlight java %} 324 | public class HelloWorld { 325 | public static void main(String[] args) { 326 | System.out.println("Hello, World!"); 327 | } 328 | } 329 | {% endhighlight %} 330 |
331 | 332 |
333 | JavaScript 334 | ---------- 335 | 336 | {% highlight js %} 337 | document.write('Hello, World!'); 338 | {% endhighlight %} 339 |
340 | 341 |
342 | Logtalk 343 | ------- 344 | 345 | {% highlight logtalk %} 346 | ?- write('Hello, World!'), nl. 347 | {% endhighlight %} 348 |
349 | 350 |
351 | Lua 352 | --- 353 | 354 | {% highlight lua %} 355 | print "Hello, World!" 356 | {% endhighlight %} 357 |
358 | 359 |
360 | Matlab 361 | ------ 362 | 363 | {% highlight matlab %} 364 | disp('Hello, World!') 365 | {% endhighlight %} 366 |
367 | 368 |
369 | MiniD 370 | ----- 371 | 372 | {% highlight minid %} 373 | module test 374 | writeln("Hello, World!") 375 | {% endhighlight %} 376 |
377 | 378 |
379 | Modelica 380 | -------- 381 | 382 | {% highlight modelica %} 383 | model HelloWorld "A differential equation" 384 | annotation(...); 385 | Real x(start=1); 386 | equation 387 | der(x)=-x; 388 | end HelloWorld; 389 | {% endhighlight %} 390 |
391 | 392 |
393 | Modula-2 394 | -------- 395 | 396 | {% highlight modula2 %} 397 | MODULE Hello; 398 | 399 | FROM InOut IMPORT WriteLn, WriteString; 400 | 401 | BEGIN 402 | WriteString ("Hello, World!"); 403 | WriteLn 404 | END Hello. 405 | {% endhighlight %} 406 |
407 | 408 |
409 | Modula-2 R10 410 | ------------ 411 | 412 | {% highlight modula2 %} 413 | MODULE Hello; 414 | 415 | IMPORT PervasiveIO; 416 | 417 | BEGIN 418 | WRITE("Hello, World!\n"); 419 | END Hello. 420 | {% endhighlight %} 421 |
422 | 423 |
424 | MuPad 425 | ----- 426 | 427 | {% highlight mupad %} 428 | t := plot::Text2d("Hello, World", [1, 1], TextFont = [24]): 429 | plot(t) 430 | {% endhighlight %} 431 |
432 | 433 |
434 | Nemerle 435 | ------- 436 | 437 | {% highlight nemerle %} 438 | System.Console.WriteLine("Hello, World!"); 439 | {% endhighlight %} 440 |
441 | 442 |
443 | Nimrod 444 | ------ 445 | 446 | {% highlight nimrod %} 447 | echo("Hello, World!") 448 | {% endhighlight %} 449 |
450 | 451 |
452 | Objective-C 453 | ----------- 454 | 455 | {% highlight objc %} 456 | #import 457 | 458 | int main(int argc, char *argv[]) 459 | { 460 | NSLog(@"Hello, World!\n"); 461 | return 0; 462 | } 463 | {% endhighlight %} 464 |
465 | 466 |
467 | Objective-J 468 | ----------- 469 | 470 | {% highlight objj %} 471 | document.write("Hello, World!"); 472 | {% endhighlight %} 473 |
474 | 475 |
476 | Octave 477 | ------ 478 | 479 | {% highlight octave %} 480 | printf("Hello, World!\n"); 481 | {% endhighlight %} 482 |
483 | 484 |
485 | OCaml 486 | ----- 487 | 488 | {% highlight ocaml %} 489 | print_string "Hello, World!\n" 490 | {% endhighlight %} 491 |
492 | 493 |
494 | Perl 495 | ---- 496 | 497 | {% highlight perl %} 498 | print "Hello, World!\n"; 499 | {% endhighlight %} 500 |
501 | 502 |
503 | PHP 504 | --- 505 | 506 | {% highlight php %} 507 | print("Hello, World!"); 508 | {% endhighlight %} 509 |
510 | 511 |
512 | PovRay 513 | ------ 514 | 515 | {% highlight pov %} 516 | #include "colors.inc" 517 | 518 | camera { 519 | location <3, 1, -10> 520 | look_at <3,0,0> 521 | } 522 | 523 | light_source { <500,500,-1000> White } 524 | 525 | text { 526 | ttf "timrom.ttf" "Hello, World!" 1, 0 527 | pigment { White } 528 | } 529 | {% endhighlight %} 530 |
531 | 532 |
533 | PostScript 534 | ---------- 535 | 536 | {% highlight postscript %} 537 | (Hello, World!\n) print quit 538 | {% endhighlight %} 539 |
540 | 541 |
542 | PowerShell 543 | ---------- 544 | 545 | {% highlight powershell %} 546 | Write-Host 'Hello, World!`n' 547 | {% endhighlight %} 548 |
549 | 550 |
551 | Prolog 552 | ------ 553 | 554 | {% highlight prolog %} 555 | write('Hello, World!'). 556 | {% endhighlight %} 557 |
558 | 559 |
560 | Python 561 | ------ 562 | 563 | {% highlight python %} 564 | print "Hello, World!" 565 | {% endhighlight %} 566 |
567 | 568 |
569 | R and S and S-Plus 570 | ------------------ 571 | 572 | {% highlight r %} 573 | cat("Hello, World!\n") 574 | {% endhighlight %} 575 |
576 | 577 |
578 | Rebol 579 | ----- 580 | 581 | {% highlight rebol %} 582 | print "Hello, World!" 583 | {% endhighlight %} 584 |
585 | 586 |
587 | Redcode 588 | ------- 589 | 590 | {% highlight redcode %} 591 | write sts.a hello, 0 592 | sts.b }write, 0 593 | djn write, #7 594 | 595 | hello dat 72, 101 ; He 596 | dat 108, 108 ; ll 597 | dat 111, 44 ; o, 598 | dat 32, 87 ; W 599 | dat 111, 114 ; or 600 | dat 108, 100 ; ld 601 | dat 33, 10 ; !\n 602 | {% endhighlight %} 603 |
604 | 605 |
606 | Reia 607 | ---- 608 | 609 | "Hello, World!".puts() 610 |
611 | 612 |
613 | Ruby and JRuby 614 | -------------- 615 | 616 | {% highlight ruby %} 617 | puts "Hello, World!" 618 | {% endhighlight %} 619 |
620 | 621 |
622 | Scala 623 | ----- 624 | 625 | {% highlight scala %} 626 | object HelloWorld { 627 | def main(args: Array[String]) { 628 | println("Hello, World!") 629 | } 630 | } 631 | {% endhighlight %} 632 |
633 | 634 |
635 | Scheme 636 | ------ 637 | 638 | {% highlight scheme %} 639 | (display "Hello, World!") 640 | {% endhighlight %} 641 |
642 | 643 |
644 | Scilab 645 | ------ 646 | 647 | {% highlight scilab %} 648 | mprintf('Hello, World!\n'); 649 | {% endhighlight %} 650 |
651 | 652 |
653 | Smalltalk 654 | --------- 655 | 656 | {% highlight smalltalk %} 657 | Transcript show: 'Hello, World!'. 658 | {% endhighlight %} 659 |
660 | 661 |
662 | SNOBOL 663 | ------ 664 | 665 | {% highlight snobol %} 666 | ID: HelloWorld 667 | Code: 668 | write.HelloWorld 669 | End 670 | {% endhighlight %} 671 |
672 | 673 |
674 | Tcl 675 | --- 676 | 677 | {% highlight tcl %} 678 | puts "Hello, World!" 679 | {% endhighlight %} 680 |
681 | 682 |
683 | Vala 684 | ---- 685 | 686 | {% highlight vala %} 687 | void main () 688 | { 689 | print ("Hello, World!\n"); 690 | } 691 | {% endhighlight %} 692 |
693 | 694 |
695 | Verilog 696 | ------- 697 | 698 | {% highlight v %} 699 | module main(); 700 | initial begin 701 | #0 $display("Hello, World!"); 702 | #1 $finish; 703 | end 704 | endmodule 705 | {% endhighlight %} 706 |
707 | 708 |
709 | VHDL 710 | ---- 711 | 712 | {% highlight vhdl %} 713 | use std.textio.all; 714 | 715 | entity Hello is 716 | end Hello; 717 | 718 | architecture Hello_Arch of Hello is 719 | begin 720 | p : process 721 | variable l:line; 722 | begin 723 | write(l, String'("Hello, World!")); 724 | writeline(output, l); 725 | wait; 726 | end process; 727 | end Hello_Arch; 728 | {% endhighlight %} 729 |
730 | 731 |
732 | Visual Basic.NET 733 | ---------------- 734 | 735 | {% highlight vbnet %} 736 | Module HelloWorldApp 737 | Sub Main() 738 | System.Console.WriteLine("Hello, World!") 739 | End Sub 740 | End Module 741 | {% endhighlight %} 742 |
743 | 744 |
745 | XQuery 746 | ------ 747 | 748 | {% highlight xquery %} 749 | let $i := "Hello, World!" 750 | return $i 751 | {% endhighlight %} 752 |
753 | --------------------------------------------------------------------------------