DEV Community

aly quey
aly quey

Posted on

Simple memorization

I know ||=, but I have to know more feature of this.

  • Simple simple
class Smile
  attr_accessor :smile

  def ensmile
    @smile = "SMILE"
  end
end
Enter fullscreen mode Exit fullscreen mode
  • Use memo simply
class Smile
  attr_accessor :smile

  def ensmile
    @smile ||= "SMILE"
  end
end
Enter fullscreen mode Exit fullscreen mode
  • TEST With begin 1)
class Smile
  attr_accessor :smile

  def ensmile
    @smile ||= begin
      "SMILE"
    end
  end
end
Enter fullscreen mode Exit fullscreen mode
  • TEST With begin 2)
class Smile
  attr_accessor :smile

  def ensmile(cry: false)
    @smile ||= begin
      cry ? "CRY" : "SMILE"
    end
  end
end
Enter fullscreen mode Exit fullscreen mode
  • TEST includes handling error
class Smile
  SmileError = Class.new(StandardError)

  attr_accessor :smile

  def ensmile(cry: false)
    @smile ||= begin
      raise SmileError if cry
      "SMILE"
    rescue SmileError
      "CRY"
    end
  end
end
Enter fullscreen mode Exit fullscreen mode
  • Spec file
require 'spec_helper'
require_relative '../lib/smile'

RSpec.describe Smile do
  let(:smile) { described_class.new }
  describe '#ensmile' do
    it 'returns "SMILE"' do
      expect(smile.smile).to be_nil
      expect(smile.ensmile).to eq 'SMILE'
      expect(smile.smile).to eq 'SMILE'
    end

    it 'returns "CRY"' do
      expect(smile.smile).to be_nil
      expect(smile.ensmile(cry: true)).to eq 'CRY'
      expect(smile.smile).to eq 'CRY'
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

repo: https://github.com/shtakai/simple-smile

Top comments (2)

Collapse
 
jakebman profile image
jakebman

(Disclaimer - I've never written Ruby, but I'm assuming || is logical or - a || b is a if a is true, otherwise b)

I believe that ||= might not work very well if you try to memoize false.

The point of memoization is that once a value is set, you don't change it:

it 'smilers never "CRY"' do
  expect(smile.smile).to be_nil
  expect(smile.ensmile).to eq 'SMILE'
  expect(smile.ensmile(cry: true)).to eq 'SMILE'
  expect(smile.smile).to eq 'SMILE'
end

it 'criers never "SMILE"' do
  expect(smile.smile).to be_nil
  expect(smile.ensmile(cry: true)).to eq 'CRY'
  expect(smile.ensmile).to eq 'CRY'
  expect(smile.smile).to eq 'CRY'
end

Consider a boolean property instead:

class Smile
  attr_accessor :smiling

  def ensmile(cry: false)
    @smiling ||= begin
      !cry
    end
  end
end

And test that criers never smile:

it 'criers never "SMILE"' do
  expect(smile.smiling).to be_nil
  expect(smile.ensmile(cry: true)).to eq false
  expect(smile.ensmile).to eq false # Failure here
  expect(smile.smiling).to eq false # And here, for the same reason
end
Collapse
 
alyson profile image
Comment marked as low quality/non-constructive by the community. View Code of Conduct
aly quey

thank you. I'll check and fix.😃

Some comments may only be visible to logged-in visitors. Sign in to view all comments.