{"id":1528,"date":"2026-09-11T10:18:34","date_gmt":"2026-09-11T09:18:34","guid":{"rendered":"https:\/\/ruby-doc.org\/learn\/?p=1528"},"modified":"2026-09-11T11:21:28","modified_gmt":"2026-09-11T10:21:28","slug":"ruby-functional-programming","status":"publish","type":"post","link":"https:\/\/ruby-doc.org\/learn\/ruby-functional-programming\/","title":{"rendered":"Ruby Functional Programming: Practical Methods and Pipelines"},"content":{"rendered":"\n<div class=\"wp-block-group rd-article is-layout-flow wp-block-group-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Ruby functional programming uses functions and data transformations to make behaviour easier to follow and reduce unexpected changes to shared state. Ruby supports this style through methods, blocks, lambdas, and operations available on collections. These tools can be used in a conventional Ruby or Rails app without forcing the entire code base into a completely different type of program.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Start with a calculation that includes reading data from databases, doing some arithmetic, and saving updated data. Create a method that explicitly takes arguments and returns something, leaving database reads and saves outside it. Then look at the calculation without having to prepare a database or figure out which objects were modified.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1536\" height=\"1024\" src=\"https:\/\/ruby-doc.org\/learn\/wp-content\/uploads\/2026\/09\/ruby-functional-programming-featured.webp\" alt=\"Ruby gem between input cubes and a sequence of glowing transformation blocks, illustrating functional programming.\" class=\"wp-image-1585\" srcset=\"https:\/\/ruby-doc.org\/learn\/wp-content\/uploads\/2026\/09\/ruby-functional-programming-featured.webp 1536w, https:\/\/ruby-doc.org\/learn\/wp-content\/uploads\/2026\/09\/ruby-functional-programming-featured-300x200.webp 300w, https:\/\/ruby-doc.org\/learn\/wp-content\/uploads\/2026\/09\/ruby-functional-programming-featured-1024x683.webp 1024w, https:\/\/ruby-doc.org\/learn\/wp-content\/uploads\/2026\/09\/ruby-functional-programming-featured-768x512.webp 768w\" sizes=\"auto, (max-width: 1536px) 100vw, 1536px\" \/><figcaption class=\"wp-element-caption\">Functional programming techniques in Ruby compose transformations and separate calculations from side effects.<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Start with a method that returns a value<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A pure function returns the same output given the same input and has no observable side effects. When writing Ruby, try for a method that leaves both its input(s) and any external state unchanged. Try to avoid hiding any dependency (such as the current date\/time) in the method. This example calculates a total amount based upon integer amounts expressed in cents:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def total_cents(lines)\n  lines.sum do |line|\n    line.fetch(:unit_cents) * line.fetch(:quantity)\n  end\nend\n\nitems = [\n  { unit_cents: 1250, quantity: 2 },\n  { unit_cents: 300, quantity: 1 }\n]\np total_cents(items) # 2800<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The above example calls the method with an array of two records. Each record contains both a :unit_cents and a :quantity. It adds up the products of these numbers, where the product of each pair of numbers represents the total amount for that line. After calling the method, neither record nor external state is changed by this calculation under the stated input contract. The caller supplies all necessary integers for this example&#8217;s contract. This example performs only arithmetic. It is not a complete pricing or accounting system.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>fetch<\/code> raises an exception instead of silently returning <code>nil<\/code> if it attempts to retrieve an absent required key. You still must establish a policy for invalid values. You could choose to refuse them at an input boundary or validate them inside the method. Do not hide either choice behind a convenient conversion.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Ruby functional programming with Enumerable<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ruby&#8217;s <a href=\"https:\/\/docs.ruby-lang.org\/en\/3.4\/Enumerable.html\">Enumerable documentation<\/a> describes operations for selecting, transforming and combining items. A short pipeline can make those separate jobs visible:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>invoices = [\n  { paid: true, total_cents: 2800 },\n  { paid: false, total_cents: 900 },\n  { paid: true, total_cents: 1500 }\n]\n\npaid_cents = invoices\n  .select { |invoice| invoice.fetch(:paid) }\n  .map { |invoice| invoice.fetch(:total_cents) }\n\np paid_cents         # [2800, 1500]\np paid_cents.sum     # 4300\ncombined = paid_cents.reduce(0) do |sum, cents|\n  sum + cents\nend\np combined # 4300<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is equivalent to three steps: select paid invoices, extract their totals, then <code>sum<\/code> those totals. The explicit initial value in <code>reduce(0)<\/code> also ensures that the empty case will always return zero. For simple addition, sum will express the intent more clearly.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Keep the input shape clear. The example above used booleans for <code>paid<\/code>. An unchecked string field containing \u201cfalse\u201d, however, is still truthy in Ruby. Therefore, if you did not check the field correctly, you would get a different answer. Data validation and doing a calculation are distinct jobs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Ruby functional programming and mutation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Collection operations encourage a transformation style of programming, but each block still determines what happens to its objects. As shown below, the result is trimmed strings while the original strings remain unaltered:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>names = [\" Ada \", \" Matz \"]\nclean_names = names.map { |name| name.strip }\n\np names       # [\" Ada \", \" Matz \"]\np clean_names # [\"Ada\", \"Matz\"]<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If each string in the block were altered in place, then creating a new result array would not protect the original strings. While reviewing your code, consider both the container operation you\u2019re using and the operations contained within each block. There\u2019s still potential for creating a new container while sharing some mutable objects among the new and old containers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An exclamation point usually indicates a more hazardous option that may include mutation. It doesn\u2019t provide a universal indicator for side effects. Instead of relying solely on the method name, examine its contract.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Freeze is useful, but it is shallow<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The Object#freeze documentation explains how to prevent changes to an object. Freezing a container does not recursively freeze every object it references:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>record = { tags: [\"new\"] }.freeze\nrecord.fetch(:tags) &lt;&lt; \"checked\"\np record.fetch(:tags) # [\"new\", \"checked\"]<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The hash is frozen, but the array stored under <code>:tags<\/code> remains mutable. Replacing the hash entry would fail; changing that nested array does not. This distinction matters when a supposedly fixed configuration contains arrays, hashes or strings.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For a smaller input structure, decide which objects must stay fixed and intentionally create and freeze them yourself. Working with much larger structures requires you to define ownership of the data before adding additional deep-freeze helpers throughout your application. Both copying and freezing incur costs as well. They don\u2019t eliminate the necessity for a clear data contract.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Pass behaviour with a lambda<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/rubyapi.org\/3.4\/o\/proc?utm_source=chatgpt.com\">A lambda is a callable Proc<\/a> with lambda-specific argument and return behaviour. The Proc reference documents those differences. A lambda is useful when a method needs a small piece of behaviour rather than a fixed value:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>add_handling = -&gt;(cents) { cents + 75 }\np [100, 200].map(&amp;add_handling) # [175, 275]<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The &amp; symbol passes the callable as a block to <code>map<\/code>. The example has one input parameter and adds a fixed handling amount to it. A named method would have been equally valid if the operation had a meaningful place in the application.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Both blocks and lambdas can capture variables from their surrounding scope as closures. Captured values can mask changing inputs. When a captured configuration value changes then a previously specified set of explicit arguments may produce different results. Pass changing dependencies explicitly when predictable behavior is important.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Use lazy evaluation when you need a bounded result<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A long chain of eager operations may build intermediate arrays. Enumerator::Lazy lets you defer parts of a pipeline until values are requested:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>odd_squares = (1..).lazy\n  .select { |number| number.odd? }\n  .map { |number| number * number }\n  .take(4)\n  .force\n\np odd_squares # [1, 9, 25, 49]<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">There is no defined maximum value for the range. The pipeline stops once it reaches four matches as requested. That terminating condition is very important \u2014 indefinitely producing an infinite sequence without knowing when it will stop would never terminate.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lazy evaluation does not automatically cause parallel execution nor necessarily speed up processing for small datasets. Use lazy evaluation when delayed consumption resolves a particular issue, then evaluate memory usage and run times. Also verify that each operation in the pipeline maintains the level of laziness that you require.<\/p>\n\n\n\n<div class=\"wp-block-group rd-guide is-layout-flow wp-block-group-is-layout-flow\">\n<h2 class=\"wp-block-heading\">Explore a project situation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Open the situation closest to your work. Compare the alternatives before choosing a first experiment.<\/p>\n\n\n\n<details class=\"wp-block-details rdc-disclosure is-layout-flow wp-block-details-is-layout-flow\"><summary>A calculation is difficult to test<\/summary>\n<p class=\"wp-block-paragraph\">Extract a method that accepts plain input and returns a value. Check the empty case and confirm the input stays unchanged.<\/p>\n<\/details>\n\n\n\n<details class=\"wp-block-details rdc-disclosure is-layout-flow wp-block-details-is-layout-flow\"><summary>A pipeline unexpectedly changes its source<\/summary>\n<p class=\"wp-block-paragraph\">Inspect the container method and every block operation. A new array can still contain shared mutable objects.<\/p>\n<\/details>\n\n\n\n<details class=\"wp-block-details rdc-disclosure is-layout-flow wp-block-details-is-layout-flow\"><summary>A sequence is large or endless<\/summary>\n<p class=\"wp-block-paragraph\">Use lazy operations with a clear consumption bound. Confirm the chain terminates and produces the expected values.<\/p>\n<\/details>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Ruby functional programming in a Rails workflow<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Real-world applications typically read files, write records to databases and send emails. Functional styles of programming do not preclude these types of jobs; however they help separate those jobs from calculations making it easier to analyze the order of side effects.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inside a Rails feature, a controller or job may gather records from a database, create plain data for input into a calculation and subsequently act on the result of that calculation. Calculations may be tested separately. The overall process still needs integration testing for authorization, transactions and error handling.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Start with one troublesome calculation and compare the before-and-after clarity. Avoid replacing straightforward code with long chains of cryptic blocks. The next developer should be able to explain what data enters, what value leaves and what state changes. For more small programs to practise with, see our <a href=\"https:\/\/ruby-doc.org\/learn\/ruby-code-examples\/\">Ruby code examples<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For the total method, test an empty collection, multiple line items and a missing required key. Preserve a copy of the original input and compare it with the input after the call to check for mutation. For lazy pipelines, test the generated values as well as the count returned. These checks cover arithmetic, input contracts, mutation and termination. A long list of assertions simply mirroring each line of implementation would give less assurance against refactoring your calculations.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Frequently asked questions<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Is Ruby a purely functional language?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No. Ruby supports mutable objects and side effects in addition to supporting various tools designed specifically for functional programming style. You can incorporate specific aspects of functional programming techniques within Ruby\u2019s object-oriented paradigm.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Does map make code pure?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No. The block passed to map can modify objects, read changing external state or perform I\/O operations; therefore review what operations occur within the block itself versus merely examining the name of the collection method invoked.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Should every method become a lambda?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No. Named methods generally aid discovery and explanation better than anonymous ones. Consider using a lambda when passing or storing behavior aids clarity in surrounding code.<\/p>\n\n\n\n<div class=\"wp-block-group rd-trust is-layout-flow wp-block-group-is-layout-flow\"><\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Use functional techniques in ordinary Ruby: make inputs explicit, transform collections and keep state changes at understandable boundaries.<\/p>\n","protected":false},"author":3,"featured_media":1585,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-1528","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programming"],"blocksy_meta":{"styles_descriptor":{"styles":{"desktop":"","tablet":"","mobile":""},"google_fonts":[],"version":7}},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Ruby Functional Programming: A Practical Guide<\/title>\n<meta name=\"description\" content=\"Learn Ruby functional programming with tested examples of pure methods, Enumerable pipelines, lambdas, shallow freeze and lazy evaluation.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/ruby-doc.org\/learn\/ruby-functional-programming\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Ruby Functional Programming: A Practical Guide\" \/>\n<meta property=\"og:description\" content=\"Learn Ruby functional programming with tested examples of pure methods, Enumerable pipelines, lambdas, shallow freeze and lazy evaluation.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/ruby-doc.org\/learn\/ruby-functional-programming\/\" \/>\n<meta property=\"og:site_name\" content=\"Ruby-Doc Learn\" \/>\n<meta property=\"article:published_time\" content=\"2026-09-11T09:18:34+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-11T10:21:28+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/ruby-doc.org\/learn\/wp-content\/uploads\/2026\/09\/ruby-functional-programming-featured.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"1536\" \/>\n\t<meta property=\"og:image:height\" content=\"1024\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"James Britt\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"James Britt\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/ruby-functional-programming\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/ruby-functional-programming\\\/\"},\"author\":{\"@id\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/james-britt\\\/#james-britt\"},\"headline\":\"Ruby Functional Programming: Practical Methods and Pipelines\",\"datePublished\":\"2026-09-11T09:18:34+00:00\",\"dateModified\":\"2026-09-11T10:21:28+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/ruby-functional-programming\\\/\"},\"wordCount\":1392,\"publisher\":{\"@id\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/ruby-functional-programming\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/ruby-functional-programming-featured.webp\",\"articleSection\":[\"Programming\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/ruby-functional-programming\\\/\",\"url\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/ruby-functional-programming\\\/\",\"name\":\"Ruby Functional Programming: A Practical Guide\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/ruby-functional-programming\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/ruby-functional-programming\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/ruby-functional-programming-featured.webp\",\"datePublished\":\"2026-09-11T09:18:34+00:00\",\"dateModified\":\"2026-09-11T10:21:28+00:00\",\"description\":\"Learn Ruby functional programming with tested examples of pure methods, Enumerable pipelines, lambdas, shallow freeze and lazy evaluation.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/ruby-functional-programming\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/ruby-functional-programming\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/ruby-functional-programming\\\/#primaryimage\",\"url\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/ruby-functional-programming-featured.webp\",\"contentUrl\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/ruby-functional-programming-featured.webp\",\"width\":1536,\"height\":1024,\"caption\":\"Functional programming techniques in Ruby compose transformations and separate calculations from side effects.\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/ruby-functional-programming\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Ruby Functional Programming: Practical Methods and Pipelines\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/#website\",\"url\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/\",\"name\":\"Ruby-Doc Learn\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/#organization\",\"name\":\"Ruby-Doc Learn\",\"url\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/ruby-doc-logo-transparent.png\",\"contentUrl\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/ruby-doc-logo-transparent.png\",\"width\":1650,\"height\":305,\"caption\":\"Ruby-Doc Learn\"},\"image\":{\"@id\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/james-britt\\\/#james-britt\",\"name\":\"James Britt\",\"image\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/jgb_self-portrait-20140914.png\",\"description\":\"Creator and long-term maintainer of Ruby-Doc.org, founder of Neurogami, and author of practical Ruby tutorials for Ruby-Doc Learn.\",\"sameAs\":[\"https:\\\/\\\/jamesbritt.com\\\/\",\"https:\\\/\\\/neurogami.com\\\/\",\"https:\\\/\\\/www.oreilly.com\\\/pub\\\/au\\\/2595\",\"https:\\\/\\\/www.rubyevents.org\\\/profiles\\\/james-britt\"],\"url\":\"https:\\\/\\\/ruby-doc.org\\\/learn\\\/james-britt\\\/\",\"jobTitle\":\"Ruby developer and writer\",\"knowsAbout\":[\"Ruby programming language\",\"Ruby documentation\",\"JRuby\",\"Open Sound Control\",\"Software development\"],\"affiliation\":{\"@type\":\"Organization\",\"name\":\"Ruby-Doc.org\",\"url\":\"https:\\\/\\\/ruby-doc.org\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Ruby Functional Programming: A Practical Guide","description":"Learn Ruby functional programming with tested examples of pure methods, Enumerable pipelines, lambdas, shallow freeze and lazy evaluation.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/ruby-doc.org\/learn\/ruby-functional-programming\/","og_locale":"en_US","og_type":"article","og_title":"Ruby Functional Programming: A Practical Guide","og_description":"Learn Ruby functional programming with tested examples of pure methods, Enumerable pipelines, lambdas, shallow freeze and lazy evaluation.","og_url":"https:\/\/ruby-doc.org\/learn\/ruby-functional-programming\/","og_site_name":"Ruby-Doc Learn","article_published_time":"2026-09-11T09:18:34+00:00","article_modified_time":"2026-09-11T10:21:28+00:00","og_image":[{"width":1536,"height":1024,"url":"https:\/\/ruby-doc.org\/learn\/wp-content\/uploads\/2026\/09\/ruby-functional-programming-featured.webp","type":"image\/webp"}],"author":"James Britt","twitter_card":"summary_large_image","twitter_misc":{"Written by":"James Britt","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/ruby-doc.org\/learn\/ruby-functional-programming\/#article","isPartOf":{"@id":"https:\/\/ruby-doc.org\/learn\/ruby-functional-programming\/"},"author":{"@id":"https:\/\/ruby-doc.org\/learn\/james-britt\/#james-britt"},"headline":"Ruby Functional Programming: Practical Methods and Pipelines","datePublished":"2026-09-11T09:18:34+00:00","dateModified":"2026-09-11T10:21:28+00:00","mainEntityOfPage":{"@id":"https:\/\/ruby-doc.org\/learn\/ruby-functional-programming\/"},"wordCount":1392,"publisher":{"@id":"https:\/\/ruby-doc.org\/learn\/#organization"},"image":{"@id":"https:\/\/ruby-doc.org\/learn\/ruby-functional-programming\/#primaryimage"},"thumbnailUrl":"https:\/\/ruby-doc.org\/learn\/wp-content\/uploads\/2026\/09\/ruby-functional-programming-featured.webp","articleSection":["Programming"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/ruby-doc.org\/learn\/ruby-functional-programming\/","url":"https:\/\/ruby-doc.org\/learn\/ruby-functional-programming\/","name":"Ruby Functional Programming: A Practical Guide","isPartOf":{"@id":"https:\/\/ruby-doc.org\/learn\/#website"},"primaryImageOfPage":{"@id":"https:\/\/ruby-doc.org\/learn\/ruby-functional-programming\/#primaryimage"},"image":{"@id":"https:\/\/ruby-doc.org\/learn\/ruby-functional-programming\/#primaryimage"},"thumbnailUrl":"https:\/\/ruby-doc.org\/learn\/wp-content\/uploads\/2026\/09\/ruby-functional-programming-featured.webp","datePublished":"2026-09-11T09:18:34+00:00","dateModified":"2026-09-11T10:21:28+00:00","description":"Learn Ruby functional programming with tested examples of pure methods, Enumerable pipelines, lambdas, shallow freeze and lazy evaluation.","breadcrumb":{"@id":"https:\/\/ruby-doc.org\/learn\/ruby-functional-programming\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ruby-doc.org\/learn\/ruby-functional-programming\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ruby-doc.org\/learn\/ruby-functional-programming\/#primaryimage","url":"https:\/\/ruby-doc.org\/learn\/wp-content\/uploads\/2026\/09\/ruby-functional-programming-featured.webp","contentUrl":"https:\/\/ruby-doc.org\/learn\/wp-content\/uploads\/2026\/09\/ruby-functional-programming-featured.webp","width":1536,"height":1024,"caption":"Functional programming techniques in Ruby compose transformations and separate calculations from side effects."},{"@type":"BreadcrumbList","@id":"https:\/\/ruby-doc.org\/learn\/ruby-functional-programming\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/ruby-doc.org\/learn\/"},{"@type":"ListItem","position":2,"name":"Ruby Functional Programming: Practical Methods and Pipelines"}]},{"@type":"WebSite","@id":"https:\/\/ruby-doc.org\/learn\/#website","url":"https:\/\/ruby-doc.org\/learn\/","name":"Ruby-Doc Learn","description":"","publisher":{"@id":"https:\/\/ruby-doc.org\/learn\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/ruby-doc.org\/learn\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/ruby-doc.org\/learn\/#organization","name":"Ruby-Doc Learn","url":"https:\/\/ruby-doc.org\/learn\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ruby-doc.org\/learn\/#\/schema\/logo\/image\/","url":"https:\/\/ruby-doc.org\/learn\/wp-content\/uploads\/2026\/09\/ruby-doc-logo-transparent.png","contentUrl":"https:\/\/ruby-doc.org\/learn\/wp-content\/uploads\/2026\/09\/ruby-doc-logo-transparent.png","width":1650,"height":305,"caption":"Ruby-Doc Learn"},"image":{"@id":"https:\/\/ruby-doc.org\/learn\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/ruby-doc.org\/learn\/james-britt\/#james-britt","name":"James Britt","image":"https:\/\/ruby-doc.org\/learn\/wp-content\/uploads\/2026\/09\/jgb_self-portrait-20140914.png","description":"Creator and long-term maintainer of Ruby-Doc.org, founder of Neurogami, and author of practical Ruby tutorials for Ruby-Doc Learn.","sameAs":["https:\/\/jamesbritt.com\/","https:\/\/neurogami.com\/","https:\/\/www.oreilly.com\/pub\/au\/2595","https:\/\/www.rubyevents.org\/profiles\/james-britt"],"url":"https:\/\/ruby-doc.org\/learn\/james-britt\/","jobTitle":"Ruby developer and writer","knowsAbout":["Ruby programming language","Ruby documentation","JRuby","Open Sound Control","Software development"],"affiliation":{"@type":"Organization","name":"Ruby-Doc.org","url":"https:\/\/ruby-doc.org\/"}}]}},"_links":{"self":[{"href":"https:\/\/ruby-doc.org\/learn\/wp-json\/wp\/v2\/posts\/1528","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ruby-doc.org\/learn\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ruby-doc.org\/learn\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ruby-doc.org\/learn\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/ruby-doc.org\/learn\/wp-json\/wp\/v2\/comments?post=1528"}],"version-history":[{"count":6,"href":"https:\/\/ruby-doc.org\/learn\/wp-json\/wp\/v2\/posts\/1528\/revisions"}],"predecessor-version":[{"id":1595,"href":"https:\/\/ruby-doc.org\/learn\/wp-json\/wp\/v2\/posts\/1528\/revisions\/1595"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ruby-doc.org\/learn\/wp-json\/wp\/v2\/media\/1585"}],"wp:attachment":[{"href":"https:\/\/ruby-doc.org\/learn\/wp-json\/wp\/v2\/media?parent=1528"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ruby-doc.org\/learn\/wp-json\/wp\/v2\/categories?post=1528"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ruby-doc.org\/learn\/wp-json\/wp\/v2\/tags?post=1528"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}