Guest User

Untitled

a guest
Jul 18th, 2018
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.60 KB | None | 0 0
  1. ##Ruby Tutorial
  2. #This tutorial is to help you get started with using Ruby.
  3.  
  4. #I Assume you have Ruby installed with a copy of 'irb'. If not then install RubyVersionManager and ruby 1.9.2 (instructs to follow)
  5.  
  6. #Starting with the most basic, this is a comment. Marked with the # symbol
  7. #I will use #=> to mean the output of a command
  8.  
  9. #The Basics
  10. 1 #This is a number, more specifically a Fixnum. An Integer value without decimal.
  11.  
  12. #You can do Maths with Fixnums as expected;
  13. 1 + 3 * 3 - 1 #=> 9
  14. (1 + 3) * (3 - 1) #=> 8
  15. 5 / 2 #=> 2 !!! Wait thats not right should be 2.5.
  16. #Calculations involving just Fixnums will return a Fixnum. Fixnum / Fixnum => Fixnum.
  17.  
  18. #When you need a decimal answer use a decimal in the calculation
  19. 5.0 / 2 #=> 2.5 #which is a Float
  20. #5 / 2.0 would have the same effect (also see type casting later)
  21. #A Fixnum in a calculation with a Float will return a Float.
  22.  
  23.  
  24. #paste this into your irb window;
  25. puts "hello World!!"
  26. #That HAS to be the easiest implementation of that age old intro to programming
  27.  
  28. "hello World!!" #Is a String
  29. #puts is a ruby method which outputs strings to the command line
  30.  
  31. "anything inside double quotes"
  32. 'or single quotes is a string object'
  33. "you can put 'single quotes' inside double without breaking the string" #Double quotes are more "powerful"
  34. "you can echo values/variables/method calls into a string like this #{5 + 2}" #The contents of the #{} is called at the time is parsed
  35.  
  36. #Ruby also has a short string class called Symbol
  37. :a_symbol #will be treated like the string "a_symbol" (but it is not a string)
  38. #Symbols can not have spaces and are prefixed with :
  39.  
  40.  
  41. #Defining and Calling Variables
  42. #Variables do not have to be pre defined
  43. my_variable = 4.2 #you just assign a variable a value with the = operator (see naming conventions later)
  44. my_variable #=> 4.2 #And call it
  45.  
  46. #A variable takes on the properties of the object Class you placed in it, therefore;
  47. my_variable.round #=> 4 because it is now a FLoat and you can call .round on a Float
  48.  
  49. #the Class of variables is dynamically reassigned
  50. var1 = 42 #var1 is now a Fixnum
  51. var1 = "a string" #var1 is now a String
  52. #There is no problem reusing a already defined variable for a different Class
  53.  
  54. a = 8039849
  55. b = 119.5
  56. c = 2893638431 #Assign some values to some variables
  57. ((a * b * 2) + c).round #Do Some maths
  58. #=> 4815162342 #Return answer (which happens to be the number from Lost!)
  59.  
  60. #Float, Fixnum Symbol and String are all different types of Class.
  61. #An instance of a Class e.g; 5 is an object. More on this later, just note that;
  62. #Everything in Ruby is an object, so everything has a Class.
  63.  
  64.  
  65. #Type Casting - Changing one class into another
  66. 2.to_f #=> 2.0 It has cast the Fixnum into a float
  67. #So you can write 5.0/2 as
  68. 5.to_f / 2 #=> 2.5
  69. #You can cast a Float to a Fixnum
  70. 2.8.to_i #=> 2 It has cast the Float into a Fixnum, note it is rounded down
  71. :ruby.to_s #=> "ruby" The symbol has been cast to a string
  72. #There are limits to what can be cast into what. For example an Array [] cannot be cast into an Integer, but a string can;
  73. "this string is not a number".to_i #=> 0
  74. "5 might get converted thou".to_i #=> 5 #A number at the beginning of a string is parsed, the rest is ignored.
  75.  
  76.  
  77. #Rounding
  78. 2.8.round #=> 3 Will also return a Fixnum this time rounded according to decimal value
  79. 2.8.floor #=> 2 #round up
  80. 2.4.ceil #=> 3 #round down
  81.  
  82. ##Equality and Comparison
  83. true #Ruby's yin and yang
  84. false #true and false are the boolean operators in Ruby, both are objects so yep they have a Class too.
  85.  
  86. 5 == 5 #=> true
  87. 5 == 4 #=> false #Basic equality test
  88.  
  89. # == can also be written with .eql? which is a method on the object 5
  90. 5.eql?(4) #=> false
  91.  
  92. true != false #=> true #The ! is the not operator in Ruby; true does not equal false returns true :)
  93. not true == false #=> true #not is synonymous with !
  94.  
  95. #greater than less than
  96. 5 > 4 #=> true
  97. 5 > 5 #=> false
  98. 5 < 5 #=> false
  99. 5 >= 5 #=> true
  100. 5 <= 5 #=> true
  101.  
  102. ##Arrays and Hashes
  103. #Arrays are indicated with square brackets []
  104. a = [] #A new empty array object (of the class Array)
  105. a = Array.new #Would have the same effect
  106.  
  107. #Arrays are linear stores for arbitrary objects. Arrays retain their order
  108. an_array = [1, 2.5, 3, "some str", true]
  109. an_array.first #=> 1
  110. an_array.last #=> true #first and last, methods on the array object
  111. an_array[1] #=> 2.5 #Accessing by index using []
  112. #NOTE Array indexes start at 0 !!!
  113.  
  114. an_array_of_arrays = [ [1,2,3], ["a", "b", "c"] ] #two arrays inside another array
  115. an_array_of_arrays[0][1] #=> 2 #the 2nd value of the 1st inner array
  116. an_array_of_arrays[1][2] #=> "c" #the 3rd value of the 2nd inner array
  117.  
  118.  
  119. #Hashes are indicated with curly brackets {}
  120. h = {} #a new empty hash object (do I need to say, class == Hash) {} == Hash.new
  121. #hashes are indexable stores for arbitrary objects. Hashes do not retain order, they store a key, value pair
  122. h = {:a_key => "a string", :true => true, :some_data => [1,2,3]}
  123. #values in hashes are addressed like arrays, only the keys is used rather than numerical index
  124. h[:some_data] #=> [1,2,3]
  125.  
  126. #Both Arrays and Hashes can be written over several lines to improve readability
  127. an_array_of_arrays = [
  128. [1,2,3],
  129. ["a", "b", "c"],
  130. "foo"
  131. ]
  132. hash = {
  133. :a_key => "a string",
  134. :true => true,
  135. :some_data => [1,2,3]
  136. }
  137.  
  138.  
  139.  
  140. ##Logic
  141. #The Good ol' If block
  142. a = (rand * 10).round #rand returns a Float between 0 and 1
  143. if a.eql?(1)
  144. puts "the value a is 1"
  145. elsif a.eql?(2)
  146. puts "the value a is 2"
  147. else
  148. puts "Im a really stupid program that can only identify 1 and 2"
  149. end# puts "the value of a is #{a}" #Would be a better!
  150.  
  151. #Ruby's unless block
  152. #Ruby syntax has a nicer way of writing if not true or if !true
  153. unless a.eql?(0) #Same as if !a.eql?(0) OR if not a.eql?(0) OR if a != 0
  154. puts "the value of a is #{a}"
  155. else
  156. puts "a was zero"
  157. end
  158.  
  159. #Ruby allows 'if / unless' to be written inline without an 'end'. If there was no need to report "a was zero" then;
  160. puts "the value of a is #{a}" unless a.eql?(0)
  161.  
  162. #AND OR && ||
  163. puts "the value of a is #{a}" unless a.eql?(0) || a.is_a?(String) # || is the OR operator
  164. #This will now only run if a is not a String or if a is not == to 0
  165. #is_a? is an equality test for class same as value.class == String
  166.  
  167. puts "the value of a is #{a}" if a.is_a?(Fixnum) && a >= 1 # && is the AND operator
  168. #&& is a "fast failing" AND. If the first assertion fails it returns without evaluating the others.
  169. #If b && a; And b is more computationally intensive it would be better to write if a && b. Thus if a is false it does not need to call b
  170. #In this case, if a is not a Fixnum then a >= 1 will not be evaluated.
  171.  
  172.  
  173. ##Loops
  174. #Loops in Ruby come in various different forms.
  175. #To call some code n number of times. The code in between the do..end is called a block.
  176. 5.times do |i|
  177. puts i
  178. end
  179. #will loop 5 times. In each loop the variable i will be available; starting with i = 0 and ending on i=4
  180. #It will however return 5 at the end (explanation later)
  181.  
  182. #loop through an array
  183. values = [1,2,3]
  184. for value in values #Now I've shown you this loop, I want you to forget it an never use it!!
  185. puts value
  186. end
  187.  
  188. values.each do |value| #This how you 'should' write a loop to iterate through an array.
  189. puts value
  190. end
  191. #The variable defined within the | | pipes is in the scope of the loop only. Once the loop as finished you could not call value
  192.  
  193. #They are both valid syntax but the first one is just a wrapper for the later.
  194. #The first one makes a nice sentence 'for thing in things' but is not interchangeable with any other Ruby loop syntax.
  195. #The latter is more akin to other aspects of Ruby (see methods and blocks later)
  196.  
  197.  
  198. #That same loop could also be written
  199. values.each {|value| puts value } #the do..end are replaced with {..}
  200.  
  201. #Variable scopes and Loops
  202. #Certain variables are available both inside and outside a loop, others are limited to just withitn the loop.
  203. s = 0
  204. values.each{|v|
  205. s = s + v #The variable s is in scope both inside and outside the loop, v is just inside the loop.
  206. } #note the { } notation is not limited to one line usage.
  207. s #=> 6 #After the loop, 's', defined before the loop is in scope.
  208. #v is not in scope anymore (see more about scope later)
  209. v #=> NameError: undefined local variable or method `v' for main:Object
  210.  
  211.  
  212. #At the end of an each loop you will be returned the object which was iterated over. After array.each{|i| #somecode } you are returned array.
  213. #This allows you to chain method calls. So in a contrived example where you want to do two loops over the same object one after the other you could say;
  214.  
  215. values.each{|value|
  216. puts "the first pass outputs this string with the value: #{value}" #block for the first loop
  217. }.each{|value|
  218. puts "the 2nd pass outputs this string with the value: #{value + 50}" #block for the 2nd loop
  219. }
  220. #IT would also work just fine to write it like this
  221. values.each do |value|
  222. #some code
  223. end.each do |value|
  224. #some more code
  225. end
  226. #But *I think* thats Ugly, buts that's a code style / readability question.
  227. #Ruby offers different ways to do comparable things so you can use the best one for the given job.
  228.  
  229.  
  230. #Ruby has a number of variations on the lowly loop.
  231. values.each_with_index do |value, i| #Two values are passed into the block, the element and its index (starting with 0)
  232. puts "the value in the #{i}th position is: #{value}"
  233. end
  234.  
  235. values = [1,2,3]
  236. s = values.inject{|val, next_val| val + next_val } #.inject is also a loop like each but with a twist.
  237. #On the first pass val will contain the 1st element and next_val the 2nd.
  238. #However on subsequent passes val will contain the result of the previous pass, next_val will have the next element.
  239. #In this case (over [1,2,3]) on the first pass val and next val are 1 and 2. the blocks' result is their addition so on the next pass val is 3 and next_val is 3.
  240. #On the final pass val is 6 and next_val is nil as no further elements exist so the loop ends returning 6
  241. s #=> 6
  242.  
  243. #Perhaps two of the most useful forms of loop in Ruby are .map and .select
  244. changed_values = values.map{|v| v + 1 }
  245. changed_values #=> [2,3,4] #the result of each pass is returned as a element of the resulting array (of same size)
  246.  
  247. vals = ["foo", 7, 1, 23, "bar", 3, 5, 9]
  248. vals.map{|v| v.is_a?(Fixnum) } #=> [false, true, true, true, false, true, true, true]
  249. vals.map{|v| v if v.is_a?(Fixnum) } #=> [nil, 7, 1, 23, nil, 3, 5, 9]
  250.  
  251. vals.select{|v| v.is_a?(Fixnum) } #=> [7, 1, 23, 3, 5, 9]
  252. #select is like the previous map only the 'v if' is implicit AND it removes the nil values.
  253. #select selects elements for which the block evaluates true
  254.  
  255. #Don't forget with all these examples using {} notation for the blocks that the 'do...end' notation would work just as well.
  256.  
  257.  
  258. ##Methods or Functions
  259. #A method is a named block of code encased in a def..end
  260. def a_simple_method
  261. #This method can be called but will return 'nil'
  262. end
  263.  
  264. def add_values a, b
  265. a + b
  266. end
  267. #The above method takes two arguments and sums them. It must have both arguments satisfied.
  268. #Ruby will implicitly return result of the last line in a method.
  269.  
  270. #Methods are called like this
  271. result = add_values(2, 8) #calls with args and assigns result to variable
  272. results = add_values 3, 5 #method calls can be written without the parenthesis, but some consider that sloppy. Depends on usage realy.
  273.  
  274. #Now lets change the method to make the last arg optional. if b is not supplied then it is set to be nil
  275. def add_values a, b = nil
  276. if b.nil? #Any object can have .nil? called on it. It is inherent to all classes. In fact it is inherited (see Class inheritance later)
  277. return a #return halts the method or a loop block it is within and returns the value at that line.
  278. end
  279. a + b
  280. end
  281. #This method will return a is b is not given, or if both given will add them
  282.  
  283. #Rubys inline 'if' would allow this to be written like this;
  284. def add_values a, b = nil
  285. return a if b.nil?
  286. a + b
  287. end
  288.  
  289. #NOTE nil is not the lack of an object, nil is an object itself. It can not be used to test if something exists
  290. foo.nil? #=> NameError: undefined local variable or method `foo' for main:Object
  291. foo = nil
  292. foo.nil? #=> true
  293.  
  294.  
  295. #While nil is not the same as false, it is considered false in an if context.
  296. #The previous method could be written 'return a if !b' or 'return a if not b' or better still use 'unless'
  297. def add_values a, b = nil
  298. return a unless b
  299. a + b
  300. end
  301.  
  302. #This would perhaps be the best way to write this, assuming the most of the time you do supply both arguments
  303. def add_values a, b = nil
  304. return a + b if b
  305. a
  306. end
  307.  
  308. #Now for a different method
  309. def sum_values values = Array.new #Takes one argument or sets it to [] if values not supplied
  310. return nil unless values.is_a?(Array) #don't do anything and return nil unless values is an Array
  311. values.inject{|i,j| i + j } #use inject to sum the elements in values and return implicitly
  312. end
  313.  
  314.  
  315. #method calls, map, inject select etc all return objects which can be treated as usual.
  316. #So you can call methods one after the other sequentially
  317. values = [1,2,3]
  318. values.map{|v| v + 2}.inject{|i,j| i + j}.floor.to_f #=> 12.0
  319. sum_values(values) * 2 #=> 12
  320.  
  321. #So now you have the basics of Ruby variables, methods, logic, loops and some primitive Classes
  322.  
  323. #You can define a method
  324. def sum_values values = Array.new
  325. values.inject{|i,j| i + j } if values.is_a?(Array) #same effect as above sum_values, just more compact
  326. end
  327.  
  328. #and assign data to a variable
  329. vals = [34, 53.87, 12.2, rand*10, 34.4]
  330.  
  331. #And pass the variable into the method to get a result
  332. answer = sum_values(vals)
  333. #But this all seems rather functional. Isn't Ruby meant to be Object Oriented? Yes, but you can write in both an OO and functional style.
  334.  
  335.  
  336. ##Rubys Naming Conventions
  337. #Ruby comes from japan where they are sick of tryingToRead horribleCammelCased varaiableNames likeTheses
  338. #Instead in_ruby we_use_underscored variable_and_method_names
  339.  
  340. #This is the convention;
  341.  
  342. Array #Capitalization is used for Classes and Constants
  343. Array.new #All methods are lowercase and underscored
  344. an_array = Array.new #An instance of a class (an object) is lowercase_underscored
  345.  
  346.  
  347.  
  348. ##Object Oriented - Classes
  349. #In Ruby every thing is an object and every object has a class. Also classes in Ruby are hierarchically arranged.
  350. #So far you have seen some of the basic classes like String and Array. On every class you can instantiate a new instance of that class
  351. a = Array.new
  352. s = String.new
  353. #on any object you can inquire about its class.
  354. a.class #=> Array
  355. s.class #=> String
  356. 5.class #=> Fixnum
  357.  
  358. a.class.class #=> Class
  359. #The Class of a class is Class!! wtf.
  360. #This is where you can see that everything in Ruby is a Class, and also that every class is a decedent of Class.
  361.  
  362. #Well great, what does that all mean?
  363. #The inheritance of classes means that all classes have the methods which are defined in Class.
  364. #for example you can call .nil? on any object because .nil? is defined on Class.
  365.  
  366. #So if Class is itself a class, can I do this?
  367. Class.new
  368. #Answer yes, but all you get back is a Class so its not much use.
  369. #To define a new class is like defining a method only the keyword is class not def and the name Must be CapitalisedCammelCased
  370.  
  371. class Vegetable
  372. end
  373. #And there you have it, Vegetable is now defined.
  374.  
  375. vegetable = Vegetable.new
  376. vegetable.class #=> Vegetable
  377. #But still not a very useful class. We want to have vegetables which do things.
  378.  
  379. class Vegetable
  380. def initialize weight # initialize is called when .new is called on a Class. Vegetable.new will call this method
  381. @weight = weight.to_f # @variables!! A variable with @ is in the scope of the class, not just the method. @weight can be accessed anywhere inside a vegetable
  382. end
  383. def weighs
  384. puts @weight
  385. end
  386. end
  387.  
  388. #Now we could create some vegetables with weight values and get the values back
  389. veg_1 = Vegetable.new(5)
  390. veg_2 = Vegetable.new(8)
  391.  
  392. veg_1.weighs #=> 5
  393. veg_2.weighs #=> 8
  394.  
  395. #OK now we want some different types of vegetable and this is where we use class inheritance
  396.  
  397. class Tomato < Vegetable
  398. def good_for_throwing?
  399. @weight >= 8 # returns the boolean response from >=
  400. end
  401. end
  402.  
  403. class Potato < Vegetable
  404. def poisonous?
  405. rand < 0.1
  406. end
  407. end
  408.  
  409. tomato = Tomato.new(9)
  410. potato = Potato.new(5)
  411.  
  412. [tomato, potato].map{|veg| veg.weighs} #=> [9,5] #map the weights from each veg
  413.  
  414. tomato.good_for_throwing? #=> true
  415. potato.poisonous? #=> rand dependent output
  416.  
  417. #We now have two classes which share some common methods but which behave differently.
  418. #You can now create groups of objects of these classes.
  419.  
  420. #Ruby allows classes to be redefined at runtime. This means you can use an existing class, but modify it during execution.
  421. #Assuming that you pasted the above code defining Vegetable and its sub classes into your irb window, paste this in.
  422.  
  423. class Vegetable
  424. def eat_a_bit bit = rand
  425. return "none left" if @weight <= 0
  426. @weight -= bit
  427. end
  428. end
  429.  
  430.  
  431. #The Existing Vegetable class has now been patched with a new method. You can now call .eat_a_bit on any vegetable.
  432.  
  433. potato.eat_a_bit
  434.  
  435. #Going back to the earlier example of using a method to sum values in an array, we can now put that method into Array itself
  436.  
  437. vals = [34, 53.87, 12.2, rand*10, 34.4]
  438. #Currently calling vals.sum will not work. There is no .sum method. So we need to define one.
  439. class Array
  440. def sum
  441. self.inject{|i,j| i + j } #self is a references to the instance of that class. It has replaced the call to values from sum_values before.
  442. end
  443. end
  444. #And now there is!!
  445. #The code you add will replace existing methods of the same name but leaves the rest unchanged.
  446. vals.sum #=> 6
  447.  
  448.  
  449. #Now you have the basics of creating a class and extending existing classes. With the definition of methods is all there really is to it.
  450.  
  451.  
  452. ##Advanced Stuff
  453.  
  454. #When you define a method it is a block of code which has a name. When you use a loop the block of code inside the loop is nameless.
  455. #There is another nameless block which is simple called a 'block' and uses &blk to represent it.
  456.  
  457. #You can define a method with takes &blk as an argument. It can only take one &blk and it must be the last arg.
  458.  
  459. def test r = rand, &blk
  460. yield(r)
  461. end
  462. #This method takes some code passed into it as &blk and 'yields' that code inside the method
  463. #it also passes r into the block with it is called (r is rand is not given)
  464.  
  465. test { puts "I don't take an arg" }
  466. test {|f| puts "I take an arg and show it #{f} inside this string" }
  467.  
  468. ans = test {|f| 5 * 3 + f }
  469.  
  470. #When passing args as well as a block the syntax to call is like this; method(variables){block}
  471. ans = test(6){|f| 5 * 3 + f }
  472.  
  473.  
  474. #This is not just useful. This is fundamental to how Ruby works.
  475. #When you call values.each{|f| #some_code} you are calling the method .each and passing it a &blk.
  476. #In all cases where a {} or do end encases some code, that is a &blk which will be yield at some point.
  477. #.each on an array will call yield on the block you passed for each element in the array and will pass the element in as the arg.
  478. #This is why the array.each{|element| #code} syntax is more regarded than the for element in array syntax.
  479.  
  480.  
  481. #Another form of nameless method is a Proc. These are like blocks but they can be assigned to variables.
  482. some_code = Proc.new{|arg|
  483. if arg.is_a?(String)
  484. puts "arg is a string"
  485. else
  486. arg * 5
  487. end
  488. }
  489.  
  490. #some_code now holds a bit of code which can be called. In this case because there is an arg it must be supplied.
  491. some_code.call("slkjflksdjf") #=> arg is a string
  492. some_code.call(5) #=> 25
Add Comment
Please, Sign In to add comment