TORFL. Test of Ruby as a foreign language

6 minute read

My first experience with Ruby was confusing.

It’s not my first programming language. At the time I knew several languages including exotic ones like AutoLISP, Prolog, Assembler. But I didn’t understand the simple Ruby code.

a = [1, 2, 3]
b = a.map { |i| 2**i }
puts b

What does this all mean? I started to find out. And what Ruby itself translate this code into:

$ ruby --dump parsetree test.rb

###########################################################
## Do NOT use this node dump for any purpose other than  ##
## debug and research.  Compatibility is not guaranteed. ##
###########################################################

# @ NODE_SCOPE (line: 3)
# +- nd_tbl: :a,:b
# +- nd_args:
# |   (null node)
# +- nd_body:
#     @ NODE_PRELUDE (line: 3)
#     +- nd_head:
#     |   (null node)
#     +- nd_body:
#     |   @ NODE_BLOCK (line: 1)
#     |   +- nd_head (1):
#     |   |   @ NODE_DASGN_CURR (line: 1)
#     |   |   +- nd_vid: :a
#     |   |   +- nd_value:
#     |   |       @ NODE_ARRAY (line: 1)
#     |   |       +- nd_alen: 3
#     |   |       +- nd_head:
#     |   |       |   @ NODE_LIT (line: 1)
#     |   |       |   +- nd_lit: 1
#     |   |       +- nd_head:
#     |   |       |   @ NODE_LIT (line: 1)
#     |   |       |   +- nd_lit: 2
#     |   |       +- nd_head:
#     |   |       |   @ NODE_LIT (line: 1)
#     |   |       |   +- nd_lit: 3
#     |   |       +- nd_next:
#     |   |           (null node)
#     |   +- nd_head (2):
#     |   |   @ NODE_DASGN_CURR (line: 2)
#     |   |   +- nd_vid: :b
#     |   |   +- nd_value:
#     |   |       @ NODE_ITER (line: 2)
#     |   |       +- nd_iter:
#     |   |       |   @ NODE_CALL (line: 2)
#     |   |       |   +- nd_mid: :map
#     |   |       |   +- nd_recv:
#     |   |       |   |   @ NODE_DVAR (line: 2)
#     |   |       |   |   +- nd_vid: :a
#     |   |       |   +- nd_args:
#     |   |       |       (null node)
#     |   |       +- nd_body:
#     |   |           @ NODE_SCOPE (line: 2)
#     |   |           +- nd_tbl: :i
#     |   |           +- nd_args:
#     |   |           |   @ NODE_ARGS (line: 2)
#     |   |           |   +- nd_ainfo->pre_args_num: 1
#     |   |           |   +- nd_ainfo->pre_init:
#     |   |           |   |   (null node)
#     |   |           |   +- nd_ainfo->post_args_num: 0
#     |   |           |   +- nd_ainfo->post_init:
#     |   |           |   |   (null node)
#     |   |           |   +- nd_ainfo->first_post_arg: (null)
#     |   |           |   +- nd_ainfo->rest_arg: (null)
#     |   |           |   +- nd_ainfo->block_arg: (null)
#     |   |           |   +- nd_ainfo->opt_args:
#     |   |           |   |   (null node)
#     |   |           |   +- nd_ainfo->kw_args:
#     |   |           |       (null node)
#     |   |           |   +- nd_ainfo->kw_rest_arg:
#     |   |           |       (null node)
#     |   |           +- nd_body:
#     |   |               @ NODE_CALL (line: 2)
#     |   |               +- nd_mid: :**
#     |   |               +- nd_recv:
#     |   |               |   @ NODE_LIT (line: 2)
#     |   |               |   +- nd_lit: 2
#     |   |               +- nd_args:
#     |   |                   @ NODE_ARRAY (line: 2)
#     |   |                   +- nd_alen: 1
#     |   |                   +- nd_head:
#     |   |                   |   @ NODE_DVAR (line: 2)
#     |   |                   |   +- nd_vid: :i
#     |   |                   +- nd_next:
#     |   |                       (null node)
#     |   +- nd_head (3):
#     |       @ NODE_FCALL (line: 3)
#     |       +- nd_mid: :puts
#     |       +- nd_args:
#     |           @ NODE_ARRAY (line: 3)
#     |           +- nd_alen: 1
#     |           +- nd_head:
#     |           |   @ NODE_DVAR (line: 3)
#     |           |   +- nd_vid: :b
#     |           +- nd_next:
#     |               (null node)
#     +- nd_compile_option:
#         +- coverage_enabled: true

Any guess? Ruby call it “blocks” — expressions in curve braces {}. And it passes blocks with its own arguments to methods. In this example degrees of 2.

That’s it.

All other Ruby expressions are easy to understand. And in general Ruby is very easy-learning programming language. Metz (inventor of Ruby) said that Ruby is designed to make programmers happy. So it is a programming language for programmers.

Tags:

Updated: