changeset 17:61dfac9a058a

Add some initial experiments with blocks
author IBBoard <dev@ibboard.co.uk>
date Tue, 03 Jan 2017 20:58:19 +0000
parents 8d46064c9afc
children e58952c15e5e
files 1-Ruby/code-blocks-irb.output 1-Ruby/code-blocks-ruby.output 1-Ruby/code-blocks.rb
diffstat 3 files changed, 128 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/1-Ruby/code-blocks-irb.output	Tue Jan 03 20:58:19 2017 +0000
@@ -0,0 +1,70 @@
+code-blocks.rb(main):001:0> #! /usr/bin/env ruby
+code-blocks.rb(main):002:0* 
+code-blocks.rb(main):003:0* # Simple passing of code block
+code-blocks.rb(main):004:0* 3.times { puts 'Repeated string' }
+Repeated string
+Repeated string
+Repeated string
+=> 3
+code-blocks.rb(main):005:0> 
+code-blocks.rb(main):006:0* # Extending a class
+code-blocks.rb(main):007:0* class Fixnum
+code-blocks.rb(main):008:1> 	def my_times
+code-blocks.rb(main):009:2> 		# We're in a number, so store it as an iterator
+code-blocks.rb(main):010:2* 		i = self
+code-blocks.rb(main):011:2> 		until i == 0
+code-blocks.rb(main):012:3> 			i = i - 1
+code-blocks.rb(main):013:3> 			# Magic happens here!
+code-blocks.rb(main):014:3* 			# Yield normally yields a value, but somehow we're executing a block…
+code-blocks.rb(main):015:3* 			yield
+code-blocks.rb(main):016:3> 		end
+code-blocks.rb(main):017:2> 	end
+code-blocks.rb(main):018:1> end
+=> :my_times
+code-blocks.rb(main):019:0> 
+code-blocks.rb(main):020:0* 3.my_times { puts 'My repeated string' }
+My repeated string
+My repeated string
+My repeated string
+=> nil
+code-blocks.rb(main):021:0> 
+code-blocks.rb(main):022:0* # Blocks are objects, if you do it right - https://www.ruby-forum.com/topic/49018
+code-blocks.rb(main):023:0* my_block = proc { puts 'I am a block' }
+=> #<Proc:0x000000017361e8@code-blocks.rb:23>
+code-blocks.rb(main):024:0> puts my_block.class
+Proc
+=> nil
+code-blocks.rb(main):025:0> 
+code-blocks.rb(main):026:0* # Blocks can be passed around - "&var" says "this is a block"
+code-blocks.rb(main):027:0* def call_block(&block)
+code-blocks.rb(main):028:1> 	block.call
+code-blocks.rb(main):029:1> end
+=> :call_block
+code-blocks.rb(main):030:0> def pass_block(&block)
+code-blocks.rb(main):031:1> 	call_block(&block)
+code-blocks.rb(main):032:1> end
+=> :pass_block
+code-blocks.rb(main):033:0> pass_block { puts 'Inline block' }
+Inline block
+=> nil
+code-blocks.rb(main):034:0> pass_block &my_block
+I am a block
+=> nil
+code-blocks.rb(main):035:0> 
+code-blocks.rb(main):036:0* # Without the "&" we get "wrong number of arguments (1 for 0)" because
+code-blocks.rb(main):037:0* # a block and an argument are different somehow. This is *not* 
+code-blocks.rb(main):038:0* # because we were trying to call "my_block" and pass what it returned (nil).
+code-blocks.rb(main):039:0* # I tried. Calling a block definitely needs ".call"
+code-blocks.rb(main):040:0* #
+code-blocks.rb(main):041:0* # This page (https://mixandgo.com/blog/mastering-ruby-blocks-in-less-than-5-minutes)
+code-blocks.rb(main):042:0* # makes it cleared: ANY method can take a block independent of its arguments.
+code-blocks.rb(main):043:0* # That means that this works:
+code-blocks.rb(main):044:0* def pass_var_block(block)
+code-blocks.rb(main):045:1> 	call_block(&block)
+code-blocks.rb(main):046:1> end
+=> :pass_var_block
+code-blocks.rb(main):047:0> 
+code-blocks.rb(main):048:0* pass_var_block my_block
+I am a block
+=> nil
+code-blocks.rb(main):049:0> 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/1-Ruby/code-blocks-ruby.output	Tue Jan 03 20:58:19 2017 +0000
@@ -0,0 +1,10 @@
+Repeated string
+Repeated string
+Repeated string
+My repeated string
+My repeated string
+My repeated string
+Proc
+Inline block
+I am a block
+I am a block
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/1-Ruby/code-blocks.rb	Tue Jan 03 20:58:19 2017 +0000
@@ -0,0 +1,48 @@
+#! /usr/bin/env ruby
+
+# Simple passing of code block
+3.times { puts 'Repeated string' }
+
+# Extending a class
+class Fixnum
+	def my_times
+		# We're in a number, so store it as an iterator
+		i = self
+		until i == 0
+			i = i - 1
+			# Magic happens here!
+			# Yield normally yields a value, but somehow we're executing a block…
+			yield
+		end
+	end
+end
+
+3.my_times { puts 'My repeated string' }
+
+# Blocks are objects, if you do it right - https://www.ruby-forum.com/topic/49018
+my_block = proc { puts 'I am a block' }
+puts my_block.class
+
+# Blocks can be passed around - "&var" says "this is a block"
+def call_block(&block)
+	block.call
+end
+def pass_block(&block)
+	call_block(&block)
+end
+pass_block { puts 'Inline block' }
+pass_block &my_block
+
+# Without the "&" we get "wrong number of arguments (1 for 0)" because
+# a block and an argument are different somehow. This is *not* 
+# because we were trying to call "my_block" and pass what it returned (nil).
+# I tried. Calling a block definitely needs ".call"
+#
+# This page (https://mixandgo.com/blog/mastering-ruby-blocks-in-less-than-5-minutes)
+# makes it cleared: ANY method can take a block independent of its arguments.
+# That means that this works:
+def pass_var_block(block)
+	call_block(&block)
+end
+
+pass_var_block my_block