Guest User

Untitled

a guest
Feb 15th, 2017
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.97 KB | None | 0 0
  1. #Ruby Programming Language
  2.  
  3. #Chapter 6 Methods, Procs, Lambdas, and Closures
  4.  
  5. ##Defining methods
  6.  
  7. * to define method use `def` followed by method name
  8. * put method parameters in round brackets ()
  9. * Abnormal method termination is when method raises exception
  10. * If method terminates normally then last expression evaluated in method body will be method invocation value
  11. * `return` keyword is used to **FORCE** return from method and value of the expresion is returned if there is no expression then nil will be returned
  12. * common practice is that `return` keyword is omitted
  13. * if `return` is used with multiple values then return value is automatically converted to array
  14. * to manually return multiple values then you need to create array manually
  15.  
  16. Sample code:
  17.  
  18. ```ruby
  19. # Define a method named 'factorial' with a single parameter 'n'
  20. def factorial(n)
  21. if n < 1 # Test the argument value for validity
  22. raise "argument must be > 0"
  23. elsif n == 1 1
  24. else
  25. n * factorial(n-1)
  26. end end
  27. ```
  28.  
  29. * Defining singleton methods on object can be done with `def` keyword as shown below
  30. * Ruby treats `Fixnum`, `Symbol` and `Numeric` objects as immediate values rather than as true referances so defining singleton methods on them is prohibited
  31.  
  32. ```ruby
  33. o = "message"
  34. def o.printme
  35. puts self
  36. end
  37. o.printme
  38. ```
  39. * You can undefine method with `undef` keyword followed by method name
  40. * You can undefine method that was inherited from superclass if you don't want that class to invoke that method
  41.  
  42. ## Method names
  43.  
  44. * Method names may (but are not required to) end with an equals sign, a question mark, or an exclamation point
  45. * You can use equal sign to specify that the method is a setter
  46. * Question mark or exclamation point give no logical ability to the method but allow you to keep usefull naming conventions
  47. * Methods with question mark are naturally answering question asked by method name
  48. * Methods with exclamation mark are the one that you should use with caution like `sort!`, `exit!`
  49. * You can define unary and binary operators
  50. * Using `alias` keyword for a method name you can create alias name for that method and use this method with that alias even after it was redefined after alias statment
  51. * Alias is not the same as overload!!!
  52.  
  53. ## Method parentheses
  54.  
  55. * Parentheses in ruby can be omitted, se example:
  56.  
  57. ```ruby
  58.  
  59. puts("hello world")
  60. #is equal to
  61. puts "hello world"
  62.  
  63. ```
  64.  
  65. * But some code is ambiguous if you omitt parentheses
  66. * The best way to avoid ambiguousness is to use parentheses
  67.  
  68.  
  69. ## Method arguments
  70.  
  71. * Methods can be define with default parameter value like:
  72.  
  73. ```ruby
  74. def prefix(s, len=1)
  75. s[0,len]
  76. end
  77. ```
  78.  
  79. * Methods default value don'd need to be constant, they are evaluated when method is invoked and not at parse time
  80. * To define method that will accept arbitrary number of arguments simply put `*` before parameter name
  81. * Passing Hash as a method parameter in ruby is allowed with no curly brackets
  82. * Methods can have block arguments that can be invoked with `yield` keyword passed as non direct method parameter:
  83.  
  84. ```ruby
  85. def sample(x)
  86. yield x*x
  87. end
  88.  
  89. sample(x) {|x2| puts x2}
  90. ```
  91.  
  92. * To have better control over the block, just add another paramter to definition with `&` before parameter name
  93. * The value of that parameter will be `Proc` object
  94. * To invoke `Proc` object use `call` on block object
  95. * It is also possible to pass created `Proc` object as a method parameter created with `Proc.new`, then mentioned `&` is not necessary
  96. * Block passed with `&` must be last in the parameter liest because of method unusuall invocation
  97.  
  98. ## Procs and Lambdas
  99.  
  100. * Creating a `Proc` object:
  101.  
  102. ```ruby
  103. Proc.new {|x| x+x }
  104. proc {|x| -x }
  105. lambda {|X| x*x}
  106. ```
  107.  
  108. * `lambda` is a global function and since Ruby 1.9 it can be replaced with `->` example:
  109.  
  110. ```ruby
  111. m=->(z){z-1}
  112. ```
  113. * One benefit of `lambda` is that block can be declared with default values like this:
  114.  
  115. ```ruby
  116. zoom = ->x,y,factor=2 { [x*factor,y*factor]}
  117. ```
  118.  
  119. * `->` can be used to pass inline proc to a method like in example:
  120.  
  121. ```ruby
  122. methodName(->{x+1},->x{x-1})
  123. ```
  124.  
  125. * Regular block syntax is simpler to use in some situations
  126. * `Proc` objects can be invoked with the use of `.()`
  127. * `Proc` and `lambda` declare `arity`, it is a number of arguments it expects
  128. * If block declares default (optinal) argument then `arity` of that block will be negative number
  129. * Block with no arbitrary number of arguments declared with `*` will give `arity` 0 cause no arguments are required
  130. * `Proc` define `==` method to detemin euality between objects, but it only returns true if object is a copy, example:
  131.  
  132. ```ruby
  133. l = lambda { |x| x*x*x }
  134. c = l.dup
  135. l == c # => true
  136. # but
  137. l.object_id == c.object_id # => false, they are not the same objects
  138. ```
  139.  
  140. * `Proc` is a block and it behave like a block, `lambda` is more like a method
  141. * Calling `Proc` is yielding to a block whereas calling `lambda` is like invoking a method
  142. * Ruby gives a method `lambda?` to check if object is `lambda` of a `Proc`
  143. * `return` keyword in block will return not only from a block but from a method that yields it
  144. * `return` work differently in `lamabda` here it will return only from `lambda` because lambda is more like method itself
  145. * It means _LocalJumpError_ is not an issue in Lambdas
  146. * `break` keyword will make sense for block used with `&` statment
  147. * Breaking lambdas make no sense at all
  148. * `next` and `redo` works the same in lambda, proc or block
  149. * `retry` cannot be used in procs or lambdas it will cause _LocalJumpError_
  150. * `raise` if there is no `rescue` will propagate to the method that invoked the block
  151. * lambdas are less flexible regarding handling arguments
  152. * procs will handle less or more than required arguments than initialy declared by discarding extra arguments or assigning _nil_ to argument that was not passed to block
  153. * lambda will rise _Wrong number of arguments_ error when called with less of to many arguments
  154.  
  155. ## Closures
  156.  
  157. * Procs and lambdas are closures
  158. * If you want to return cloasures from methods then be careful about variables scope
  159. * `Proc` class defines method named `binding` that returns `Binding` object that can be used with global `eval` method
  160. * `Method` object can represent method but remember that calling it through this object is not very efficient
  161. * To obtain that object use method named `method` on object like:
  162.  
  163. ```ruby
  164. m = 0.method(:succ) # A Method representing the succ method of Fixnum 0
  165. ```
  166.  
  167. * Other method that can be used is `public_method` it works the same way but it will ignore private and protected methods
  168. * Method objects behave like lambdas so they can be prefixed with `&` and passed to another method as argument
  169. * Method objects are not closures so they have no access to local variables outside of their own scope, the only binding retained by `Method` is the value of `self`
  170. * Usefull methods declared in `Method` object are:
  171. - name - _returns method name as string_
  172. - owner - _returns in which method was defined_
  173. - receiver - _returns object to which the method is bound_
  174. * It is also possible to obtain `UnboundMethod` object using `instance_method`
  175. * to use `UnboundMethod` object it needs to be bind again to some object like this:
  176.  
  177. ```ruby
  178. plus_2 = unbound_plus.bind(2) # Bind the method to the object 2
  179. ```
  180.  
  181. ## Functional Programming
  182.  
  183. * Ruby is not a functional language but can be more or less adopted to functional style
  184. * It is possible to automate memoizing with method like:
  185.  
  186. ```ruby
  187. module Functional
  188. #
  189. # Return a new lambda that caches the results of this function and
  190. # only calls the function when new arguments are supplied.
  191. #
  192. def memoize
  193. cache = {} # An empty cache. The lambda captures this in its closure.
  194. lambda {|*args|
  195. # notice that the hash key is the entire array of arguments!
  196. unless cache.has_key?(args) # If no cached result for these args
  197. cache[args] = self[*args] # Compute and cache the result
  198. end
  199. cache[args] # Return result from cache
  200. }
  201. end
  202. # A (probably unnecessary) unary + operator for memoization
  203. # Mnemonic: the + operator means "improved"
  204. alias +@ memoize # cached_f = +f
  205. end
  206. ```
Advertisement
Add Comment
Please, Sign In to add comment