# HG changeset patch # User IBBoard # Date 1483477099 0 # Node ID 61dfac9a058aa96769c7d76598ede41302f5490d # Parent 8d46064c9afc2c59be8ccb91a5278141df019c3f Add some initial experiments with blocks diff -r 8d46064c9afc -r 61dfac9a058a 1-Ruby/code-blocks-irb.output --- /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' } +=> # +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> diff -r 8d46064c9afc -r 61dfac9a058a 1-Ruby/code-blocks-ruby.output --- /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 diff -r 8d46064c9afc -r 61dfac9a058a 1-Ruby/code-blocks.rb --- /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