Mercurial > repos > other > SevenLanguagesInSevenWeeks
diff 1-Ruby/code-blocks.rb @ 17:61dfac9a058a
Add some initial experiments with blocks
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Tue, 03 Jan 2017 20:58:19 +0000 |
parents | |
children | e58952c15e5e |
line wrap: on
line diff
--- /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