summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--c.html.markdown4
-rw-r--r--clojure.html.markdown4
-rw-r--r--dart.html.markdown4
-rw-r--r--elixir.html.markdown4
-rw-r--r--erlang.html.markdown4
-rw-r--r--fsharp.html.markdown4
-rw-r--r--haskell.html.markdown107
-rw-r--r--java.html.markdown7
-rw-r--r--javascript.html.markdown433
-rw-r--r--julia.html.markdown4
-rw-r--r--lua.html.markdown4
-rw-r--r--php.html.markdown4
-rw-r--r--python.html.markdown4
-rw-r--r--r.html.markdown4
-rw-r--r--ruby.html.markdown15
15 files changed, 547 insertions, 59 deletions
diff --git a/c.html.markdown b/c.html.markdown
index f5f28608..132f75dc 100644
--- a/c.html.markdown
+++ b/c.html.markdown
@@ -1,8 +1,8 @@
---
language: c
-author: Adam Bard
-author_url: http://adambard.com/
filename: learnc.c
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
---
Ah, C. Still the language of modern high-performance computing.
diff --git a/clojure.html.markdown b/clojure.html.markdown
index 39a27bcf..6baae0ce 100644
--- a/clojure.html.markdown
+++ b/clojure.html.markdown
@@ -1,8 +1,8 @@
---
language: clojure
-author: Adam Bard
-author_url: http://adambard.com/
filename: learnclojure.clj
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
---
Clojure is a Lisp family language developed for the Java Virtual Machine. It has
diff --git a/dart.html.markdown b/dart.html.markdown
index 27365746..34d1c6a8 100644
--- a/dart.html.markdown
+++ b/dart.html.markdown
@@ -1,8 +1,8 @@
---
language: dart
-author: Joao Pedrosa
-author_url: https://github.com/jpedrosa/
filename: learndart.dart
+contributors:
+ - ["Joao Pedrosa", "https://github.com/jpedrosa/"]
---
Dart is a newcomer into the realm of programming languages.
diff --git a/elixir.html.markdown b/elixir.html.markdown
index 2e9aa5a1..3a11ce1f 100644
--- a/elixir.html.markdown
+++ b/elixir.html.markdown
@@ -1,7 +1,7 @@
---
language: elixir
-author: Joao Marques
-author_url: http://github.com/mrshankly
+contributors:
+ - ["Joao Marques", "http://github.com/mrshankly"]
filename: learnelixir.ex
---
diff --git a/erlang.html.markdown b/erlang.html.markdown
index 42d0b809..208f31e4 100644
--- a/erlang.html.markdown
+++ b/erlang.html.markdown
@@ -1,7 +1,7 @@
---
language: erlang
-author: Giovanni Cappellotto
-author_url: http://www.focustheweb.com/
+contributor:
+ - ["Giovanni Cappellotto", "http://www.focustheweb.com/"]
filename: learnerlang.erl
---
diff --git a/fsharp.html.markdown b/fsharp.html.markdown
index b1860372..49951c78 100644
--- a/fsharp.html.markdown
+++ b/fsharp.html.markdown
@@ -1,7 +1,7 @@
---
language: F#
-author: Scott Wlaschin
-author_url: http://fsharpforfunandprofit.com/
+contributors:
+ - ["Scott Wlaschin", "http://fsharpforfunandprofit.com/"]
filename: learnfsharp.fs
---
diff --git a/haskell.html.markdown b/haskell.html.markdown
index e8d7c077..34df4d08 100644
--- a/haskell.html.markdown
+++ b/haskell.html.markdown
@@ -1,7 +1,7 @@
---
language: haskell
-author: Adit Bhargava
-author_url: http://adit.io
+contributors:
+ - ["Adit Bhargava", "http://adit.io"]
---
Haskell was designed as a practical, purely functional programming language. It's famous for
@@ -11,7 +11,7 @@ makes coding a real joy for me.
```haskell
-- Single line comments start with two dashes.
{- Multiline comments can be enclosed
-in a block like this.
+en a block like this.
-}
----------------------------------------------------
@@ -281,19 +281,20 @@ data Color = Red | Blue | Green
-- Now you can use it in a function:
-say :: Color -> IO String
-say Red = putStrLn "You are Red!"
-say Blue = putStrLn "You are Blue!"
-say Green = putStrLn "You are Green!"
+
+say :: Color -> String
+say Red = "You are Red!"
+say Blue = "You are Blue!"
+say Green = "You are Green!"
-- Your data types can have parameters too:
data Maybe a = Nothing | Just a
-- These are all of type Maybe
-Nothing
-Just "hello"
-Just 1
+Just "hello" -- of type `Maybe String`
+Just 1 -- of type `Maybe Int`
+Nothing -- of type `Maybe a` for any `a`
----------------------------------------------------
-- 8. Haskell IO
@@ -302,32 +303,78 @@ Just 1
-- While IO can't be explained fully without explaining monads,
-- it is not hard to explain enough to get going.
--- An `IO a` value is an IO action: you can chain them with do blocks
+-- When a Haskell program is executed, the function `main` is
+-- called. It must return a value of type `IO ()`. For example:
+
+main :: IO ()
+main = putStrLn $ "Hello, sky! " ++ (say Blue)
+-- putStrLn has type String -> IO ()
+
+-- It is easiest to do IO if you can implement your program as
+-- a function from String to String. The function
+-- interact :: (String -> String) -> IO ()
+-- inputs some text, runs a function on it, and prints out the
+-- output.
+
+countLines :: String -> String
+countLines = show . length . lines
+
+main' = interact countLines
+
+-- You can think of a value of type `IO ()` as representing a
+-- sequence of actions for the computer to do, much like a
+-- computer program written in an imperative language. We can use
+-- the `do` notation to chain actions together. For example:
+
+sayHello :: IO ()
+sayHello = do
+ putStrLn "What is your name?"
+ name <- getLine -- this gets a line and gives it the name "input"
+ putStrLn $ "Hello, " ++ name
+
+-- Exercise: write your own version of `interact` that only reads
+-- one line of input.
+
+-- The code in `sayHello` will never be executed, however. The only
+-- action that ever gets executed is the value of `main`.
+-- To run `sayHello` comment out the above definition of `main`
+-- and replace it with:
+-- main = sayHello
+
+-- Let's understand better how the function `getLine` we just
+-- used works. Its type is:
+-- getLine :: IO String
+-- You can think of a value of type `IO a` as representing a
+-- computer program that will generate a value of type `a`
+-- when executed (in addition to anything else it does). We can
+-- store and reuse this value using `<-`. We can also
+-- make our own action of type `IO String`:
+
action :: IO String
action = do
putStrLn "This is a line. Duh"
- input <- getLine -- this gets a line and gives it the name "input"
+ input1 <- getLine
input2 <- getLine
- return (input1 ++ "\n" ++ input2) -- This is the result of the whole action
+ -- The type of the `do` statement is that of its last line.
+ -- `return` is not a keyword, but merely a function
+ return (input1 ++ "\n" ++ input2) -- return :: String -> IO String
--- This didn't actually do anything. When a haskell program is executed
--- an IO action called "main" is read and interpreted.
+-- We can use this just like we used `getLine`:
-main = do
- putStrLn "Our first program. How exciting!"
- result <- action -- our defined action is just like the default ones
+main'' = do
+ putStrLn "I will echo two lines!"
+ result <- action
putStrLn result
putStrLn "This was all, folks!"
--- Haskell does IO through a monad because this allows it to be a purely
--- functional language. Our `action` function had a type signature of `IO String`.
--- In general any function that interacts with the outside world (i.e. does IO)
--- gets marked as `IO` in its type signature. This lets us reason about what
--- functions are "pure" (don't interact with the outside world or modify state)
--- and what functions aren't.
+-- The type `IO` is an example of a "monad". The way Haskell uses a monad to
+-- do IO allows it to be a purely functional language. Any function that
+-- interacts with the outside world (i.e. does IO) gets marked as `IO` in its
+-- type signature. This lets us reason about what functions are "pure" (don't
+-- interact with the outside world or modify state) and what functions aren't.
--- This is a powerful feature, because it's easy to run pure functions concurrently
--- so concurrency in Haskell is very easy.
+-- This is a powerful feature, because it's easy to run pure functions
+-- concurrently; so, concurrency in Haskell is very easy.
----------------------------------------------------
@@ -344,6 +391,14 @@ let foo = 5
>:t foo
foo :: Integer
+
+-- You can also run any action of type `IO ()`
+
+> sayHello
+What is your name?
+Friend!
+Hello, Friend!
+
```
There's a lot more to Haskell, including typeclasses and monads. These are the big ideas that make Haskell such fun to code in. I'll leave you with one final Haskell example: an implementation of quicksort in Haskell:
diff --git a/java.html.markdown b/java.html.markdown
index 8ba48d73..785a2cb9 100644
--- a/java.html.markdown
+++ b/java.html.markdown
@@ -1,11 +1,8 @@
---
language: java
-
-author: Jake Prather
-
-author_url: http://github.com/JakeHP
-
+contributors:
+ - ["Jake Prather", "http://github.com/JakeHP"]
filename: LearnJava.java
---
diff --git a/javascript.html.markdown b/javascript.html.markdown
new file mode 100644
index 00000000..254163e8
--- /dev/null
+++ b/javascript.html.markdown
@@ -0,0 +1,433 @@
+---
+language: javascript
+author: Adam Brenecki
+author_url: http://adam.brenecki.id.au
+---
+
+Javascript was created by Netscape's Brendan Eich in 1995. It was originally
+intended as a simpler scripting language for websites, complimenting the use of
+Java for more complex web applications, but its tight integration with Web pages
+and built-in support in browsers has caused it to become far more common than
+Java in web frontends.
+
+JavaScript isn't just limited to web browsers, though: Node.js, a project that
+provides a standalone runtime for Google Chrome's V8 JavaScript engine, is
+becoming more and more popular.
+
+Feedback would be highly appreciated! You can reach me at
+[@adambrenecki](https://twitter.com/adambrenecki), or
+[adam@brenecki.id.au](mailto:adam@brenecki.id.au).
+
+```js
+// Comments are like C. Single-line comments start with two slashes,
+/* and multiline comments start with slash-star
+ and end with star-slash */
+
+// Statements can be terminated by ;
+doStuff();
+
+// ... but they don't have to be, as semicolons are automatically inserted
+// wherever there's a newline, except in certain cases.
+doStuff()
+
+// We'll leave semicolons off here; whether you do or not will depend on your
+// personal preference or your project's style guide.
+
+///////////////////////////////////
+// 1. Numbers, Strings and Operators
+
+// Javascript has one number type (which is a 64-bit IEEE 754 double).
+3 // = 3
+1.5 // = 1.5
+
+// All the basic arithmetic works as you'd expect.
+1 + 1 // = 2
+8 - 1 // = 7
+10 * 2 // = 20
+35 / 5 // = 7
+
+// Including uneven division.
+5 / 2 // = 2.5
+
+// Bitwise operations also work; when you perform a bitwise operation your float
+// is converted to a signed int *up to* 32 bits.
+1 << 2 // = 4
+
+// Precedence is enforced with parentheses.
+(1 + 3) * 2 // = 8
+
+// There are three special not-a-real-number values:
+Infinity // result of e.g. 1/0
+-Infinity // result of e.g. -1/0
+NaN // result of e.g. 0/0
+
+// There's also a boolean type.
+true
+false
+
+// Strings are created with ' or ".
+'abc'
+"Hello, world"
+
+// Negation uses the ! symbol
+!true // = false
+!false // = true
+
+// Equality is ==
+1 == 1 // = true
+2 == 1 // = false
+
+// Inequality is !=
+1 != 1 // = false
+2 != 1 // = true
+
+// More comparisons
+1 < 10 // = true
+1 > 10 // = false
+2 <= 2 // = true
+2 >= 2 // = true
+
+// Strings are concatenated with +
+"Hello " + "world!" // = "Hello world!"
+
+// and are compared with < and >
+"a" < "b" // = true
+
+// Type coercion is performed for comparisons...
+"5" == 5 // = true
+
+// ...unless you use ===
+"5" === 5 // = false
+
+// You can access characters in a string with charAt
+"This is a string".charAt(0)
+
+// There's also null and undefined
+null // used to indicate a deliberate non-value
+undefined // used to indicate a value that hasn't been set yet
+
+// null, undefined, NaN, 0 and "" are falsy, and everything else is truthy.
+// Note that 0 is falsy and "0" is truthy, even though 0 == "0".
+
+///////////////////////////////////
+// 2. Variables, Arrays and Objects
+
+// Variables are declared with the var keyword. Javascript is dynamically typed,
+// so you don't need to specify type. Assignment uses a single = character.
+var someVar = 5
+
+// if you leave the var keyword off, you won't get an error...
+someOtherVar = 10
+
+// ...but your variable will be created in the global scope, not in the scope
+// you defined it in.
+
+// Variables declared without being assigned to are set to undefined.
+var someThirdVar // = undefined
+
+// There's shorthand for performing math operations on variables:
+someVar += 5 // equivalent to someVar = someVar + 5; someVar is 10 now
+someVar *= 10 // now someVar is 100
+
+// and an even-shorter-hand for adding or subtracting 1
+someVar++ // now someVar is 101
+someVar-- // back to 100
+
+// Arrays are ordered lists of values, of any type.
+var myArray = ["Hello", 45, true]
+
+// Their members can be accessed using the square-brackets subscript syntax.
+// Array indices start at zero.
+myArray[1] // = 45
+
+// JavaScript's objects are equivalent to 'dictionaries' or 'maps' in other
+// languages: an unordered collection of key-value pairs.
+{key1: "Hello", key2: "World"}
+
+// Keys are strings, but quotes aren't required if they're a valid
+// JavaScript identifier. Values can be any type.
+var myObj = {myKey: "myValue", "my other key": 4}
+
+// Object attributes can also be accessed using the subscript syntax,
+myObj["my other key"] // = 4
+
+// ... or using the dot syntax, provided the key is a valid identifier.
+myObj.myKey // = "myValue"
+
+// Objects are mutable; values can be changed and new keys added.
+myObj.myThirdKey = true
+
+// If you try to access a value that's not yet set, you'll get undefined.
+myObj.myFourthKey // = undefined
+
+///////////////////////////////////
+// 3. Logic and Control Structures
+
+// The if structure works as you'd expect.
+var count = 1
+if (count == 3){
+ // evaluated if count is 3
+} else if (count == 4) {
+ // evaluated if count is 4
+} else {
+ // evaluated if it's not either 3 or 4
+}
+
+// As does while.
+while (true) {
+ // An infinite loop!
+}
+
+// Do-while loops are like while loops, except they always run at least once.
+var input
+do {
+ input = getInput()
+} while (!isValid(input))
+
+// the for loop is the same as C and Java:
+// initialisation; continue condition; iteration.
+for (var i = 0; i < 5; i++){
+ // will run 5 times
+}
+
+// && is logical and, || is logical or
+if (house.size == "big" && house.colour == "blue"){
+ house.contains = "bear"
+}
+if (colour == "red" || colour == "blue"){
+ // colour is either red or blue
+}
+
+// && and || "short circuit", which is useful for setting default values.
+var name = otherName || "default"
+
+///////////////////////////////////
+// 4. Functions, Scope and Closures
+
+// JavaScript functions are declared with the function keyword.
+function myFunction(thing){
+ return thing.toUpperCase()
+}
+myFunction("foo") // = "FOO"
+
+// Functions can also be defined "anonymously" - without a name:
+function(thing){
+ return thing.toLowerCase()
+}
+// (we can't call our function, since we don't have a name to refer to it with)
+
+// JavaScript functions are first class objects, so they can be reassigned to
+// different variable names and passed to other functions as arguments - for
+// example, when supplying an event handler:
+function myFunction(){
+ // this code will be called in 5 seconds' time
+}
+setTimeout(myFunction, 5000)
+
+// You can even write the function statement directly in the call to the other
+// function.
+
+setTimeout(function myFunction(){
+ // this code will be called in 5 seconds' time
+}, 5000)
+
+// JavaScript has function scope; functions get their own scope but other blocks
+// do not.
+if (true){
+ var i = 5
+}
+i // = 5 - not undefined as you'd expect in a block-scoped language
+
+// This has led to a common pattern of "immediately-executing anonymous
+// functions", which prevent temporary variables from leaking into the global
+// scope.
+function(){
+ var temporary = 5
+ // We can access the global scope by assiging to the 'global object', which
+ // in a web browser is always 'window'. The global object may have a
+ // different name in non-browser environments such as Node.js.
+ window.permanent = 10
+ // Or, as previously mentioned, we can just leave the var keyword off.
+ permanent2 = 15
+}()
+temporary // raises ReferenceError
+permanent // = 10
+permanent2 // = 15
+
+// One of JavaScript's most powerful features is closures. If a function is
+// defined inside another function, the inner function has access to all the
+// outer function's variables.
+function sayHelloInFiveSeconds(name){
+ var prompt = "Hello, " + name + "!"
+ function inner(){
+ alert(prompt)
+ }
+ setTimeout(inner, 5000)
+ // setTimeout is asynchronous, so this function will finish without waiting
+ // 5 seconds. However, once the 5 seconds is up, inner will still have
+ // access to the value of prompt.
+}
+sayHelloInFiveSeconds("Adam") // will open a popup with "Hello, Adam!" in 5s
+
+///////////////////////////////////
+// 5. More about Objects; Constructors and Prototypes
+
+// Objects can contain functions.
+var myObj = {
+ myFunc: function(){
+ return "Hello world!"
+ }
+}
+myObj.myFunc() // = "Hello world!"
+
+// When functions attached to an object are called, they can access the object
+// they're attached to using the this keyword.
+myObj = {
+ myString: "Hello world!",
+ myFunc: function(){
+ return this.myString
+ }
+}
+myObj.myFunc() // = "Hello world!"
+
+// What this is set to has to do with how the function is called, not where
+// it's defined. So, our function doesn't work if it isn't called in the
+// context of the object.
+var myFunc = myObj.myFunc
+myFunc() // = undefined
+
+// Inversely, a function can be assigned to the object and gain access to it
+// through this, even if it wasn't attached when it was defined.
+var myOtherFunc = function(){
+ return this.myString.toUpperCase()
+}
+myObj.myOtherFunc = myOtherFunc
+myObj.myOtherFunc() // = "HELLO WORLD!"
+
+// When you call a function with the new keyword, a new object is created, and
+// made available to the function via this. Functions designed to be called
+// like this are called constructors.
+
+var MyConstructor = function(){
+ this.myNumber = 5
+}
+myNewObj = new MyConstructor() // = {myNumber: 5}
+myNewObj.myNumber // = 5
+
+// Every JavaScript object has a 'prototype'. When you go to access a property
+// on an object that doesn't exist on the actual object, the interpreter will
+// look at its prototype.
+
+// Some JS implementations let you access an object's prototype on the magic
+// property __proto__. While this is useful for explaining prototypes it's not
+// part of the standard; we'll get to standard ways of using prototypes later.
+var myObj = {
+ myString: "Hello world!",
+}
+var myPrototype = {
+ meaningOfLife: 42,
+ myFunc: function(){
+ return this.myString.toLowerCase()
+ }
+}
+myObj.__proto__ = myPrototype
+myObj.meaningOfLife // = 42
+
+// This works for functions, too.
+myObj.myFunc() // = "hello world!"
+
+// Of course, if your property isn't on your prototype, the prototype's
+// prototype is searched, and so on.
+myPrototype.__proto__ = {
+ myBoolean: true
+}
+myObj.myBoolean // = true
+
+// There's no copying involved here; each object stores a reference to its
+// prototype. This means we can alter the prototype and our changes will be
+// reflected everywhere.
+myPrototype.meaningOfLife = 43
+myObj.meaningOfLife // = 43
+
+// We mentioned that __proto__ was non-standard, and there's no standard way to
+// change the prototype of an existing object. However, there's two ways to
+// create a new object with a given prototype.
+
+// The first is Object.create, which is a recent addition to JS, and therefore
+// not available in all implementations yet.
+var myObj = Object.create(myPrototype)
+myObj.meaningOfLife // = 43
+
+// The second way, which works anywhere, has to do with constructors.
+// Constructors have a property called prototype. This is *not* the prototype of
+// the constructor function itself; instead, it's the prototype that new objects
+// are given when they're created with that constructor and the new keyword.
+myConstructor.prototype = {
+ getMyNumber: function(){
+ return self.myNumber
+ }
+}
+var myNewObj2 = new myConstructor()
+myNewObj2.getMyNumber() // = 5
+
+// Built-in types like strings and numbers also have constructors that create
+// equivalent wrapper objects.
+var myNumber = 12
+var myNumberObj = new Number(12)
+myNumber == myNumberObj // = true
+
+// Except, they aren't exactly equivalent.
+typeof(myNumber) // = 'number'
+typeof(myNumberObj) // = 'object'
+myNumber === myNumberObj // = false
+if (0){
+ // This code won't execute, because 0 is falsy.
+}
+if (Number(0)){
+ // This code *will* execute, because Number(0) is truthy.
+}
+
+// However, the wrapper objects and the regular builtins share a prototype, so
+// you can actually add functionality to a string, for instance.
+String.prototype.firstCharacter = function(){
+ return this.charAt(0)
+}
+"abc".firstCharacter() // = "a"
+
+// This fact is often used in "polyfilling", which is implementing newer
+// features of JavaScript in an older subset of JavaScript, so that they can be
+// used in older environments such as outdated browsers.
+
+// For instance, we mentioned that Object.create isn't yet available in all
+// implementations, but we can still use it with this polyfill:
+if (Object.create === undefined){ // don't overwrite it if it exists
+ Object.create = function(proto){
+ // make a temporary constructor with the right prototype
+ var Constructor = function(){}
+ Constructor.prototype = proto
+ // then use it to create a new, appropriately-prototyped object
+ return new Constructor()
+ }
+}
+```
+
+## Further Reading
+
+The [Mozilla Developer
+Network](https://developer.mozilla.org/en-US/docs/Web/JavaScript) provides
+excellent documentation for JavaScript as it's used in browsers. Plus, it's a
+wiki, so as you learn more you can help others out by sharing your own
+knowledge.
+
+MDN's [A re-introduction to
+JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
+covers much of the concepts covered here in more detail. This guide has quite
+deliberately only covered the JavaScript language itself; if you want to learn
+more about how to use JavaScript in web pages, start by learning about the
+[Document Object
+Model](https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core)
+
+In addition to direct contributors to this article, some content is adapted
+from Louie Dinh's Python tutorial on this site, and the [JS
+Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
+on the Mozilla Developer Network.
diff --git a/julia.html.markdown b/julia.html.markdown
index 6c719b5c..1023e303 100644
--- a/julia.html.markdown
+++ b/julia.html.markdown
@@ -1,7 +1,7 @@
---
language: julia
-author: Leah Hanson
-author_url: http://leahhanson.us
+contributors:
+ - ["Leah Hanson", "http://leahhanson.us"]
filename: learnjulia.jl
---
diff --git a/lua.html.markdown b/lua.html.markdown
index 4df57a92..0ece399f 100644
--- a/lua.html.markdown
+++ b/lua.html.markdown
@@ -1,7 +1,7 @@
---
language: lua
-author: Tyler Neylon
-author_url: http://tylerneylon.com/
+contributors:
+ - ["Tyler Neylon", "http://tylerneylon.com/"]
filename: learnlua.lua
---
diff --git a/php.html.markdown b/php.html.markdown
index f0c5c918..a20e1d11 100644
--- a/php.html.markdown
+++ b/php.html.markdown
@@ -1,7 +1,7 @@
---
language: php
-author: Malcolm Fell
-author_url: http://emarref.net/
+contributors:
+ - ["Malcolm Fell", "http://emarref.net/"]
filename: learnphp.php
---
diff --git a/python.html.markdown b/python.html.markdown
index fe8a204c..e7ee6fbd 100644
--- a/python.html.markdown
+++ b/python.html.markdown
@@ -1,7 +1,7 @@
---
language: python
-author: Louie Dinh
-author_url: http://ldinh.ca
+contributors:
+ - ["Louie Dinh", "http://ldinh.ca"]
filename: learnpython.py
---
diff --git a/r.html.markdown b/r.html.markdown
index 535b9065..0240e8fb 100644
--- a/r.html.markdown
+++ b/r.html.markdown
@@ -1,7 +1,7 @@
---
language: R
-author: e99n09
-author_url: http://github.com/e99n09
+contributors:
+ - ["e99n09", "http://github.com/e99n09"]
filename: learnr.r
---
diff --git a/ruby.html.markdown b/ruby.html.markdown
index 2de134ae..2c9a4cb9 100644
--- a/ruby.html.markdown
+++ b/ruby.html.markdown
@@ -1,7 +1,9 @@
---
language: ruby
+filename: learnruby.rb
contributors:
- ["David Underwood", "http://theflyingdeveloper.com"]
+ - ["Joel Walden", "http://joelwalden.net"]
---
```ruby
@@ -90,8 +92,9 @@ path_to_project_root = '/good/name/'
path = '/bad/name/'
# Symbols (are objects)
-# Symbols are immutable, reusable constants represented internally by an integer value
-# They're often used instead of strings to efficiently convey specific, meaningful values
+# Symbols are immutable, reusable constants represented internally by an
+# integer value. They're often used instead of strings to efficiently convey
+# specific, meaningful values
:pending.class #=> Symbol
@@ -154,7 +157,7 @@ new_hash = { defcon: 3, action: true}
new_hash.keys #=> [:defcon, :action]
# Tip: Both Arrays and Hashes are Enumerable
-# This means they share a lot of useful methods such as each, map, count, and more
+# They share a lot of useful methods such as each, map, count, and more
# Control structures
@@ -277,8 +280,8 @@ class Human
@name
end
- # A class method; uses self to distinguish from instance methods. (Can only be called on class, not an instance).
-
+ # A class method uses self to distinguish from instance methods.
+ $ It can only be called on the class, not an instance.
def self.say(msg)
puts "#{msg}"
end
@@ -303,4 +306,4 @@ dwight.name #=> "Dwight K. Schrute"
# Call the class method
Human.say("Hi") #=> "Hi"
-``` \ No newline at end of file
+```