Skip to content

Instantly share code, notes, and snippets.

@masasakano
Last active May 1, 2025 21:25
Show Gist options
  • Save masasakano/2feb57530fd4304b36c00f932b7216dc to your computer and use it in GitHub Desktop.
Save masasakano/2feb57530fd4304b36c00f932b7216dc to your computer and use it in GitHub Desktop.
Ruby Module to add constructor of *_(found?|created?) and their setter methods. Test file for Rails, but others can be included in any Ruby scripts.
module ModuleWasFounds
class InconsistencyInWasFoundError < StandardError # ModuleWasFounds::InconsistencyInWasFoundError
## Error in inconsistency in ModuleWasFound#was_found? and ModuleWasFound#was_created?
end
end
# -*- coding: utf-8 -*-
# Module to implement methods, primarily {#was_found?} and {#was_created?}
#
# == Description
#
# Class method +define_was_found_for(keyword)+ is also defined, with which
# +keyword_was_found?+ etc are defined.
#
# @example
# include ModuleWasFound
#
module ModuleWasFound
#def self.included(base)
# base.extend(ClassMethods)
#end
extend ActiveSupport::Concern # In Rails, the 3 lines above can be replaced with this.
# extend ModuleApplicationBase
# extend ModuleCommon
module ClassMethods
#
# Defines 4 instance methods of "*_found(=|?)" and "*_created(=|?)"
#
# Basically defines writers and readers (with a postfix of a question mark).
#
# Suppose "*" is "group". Then,
#
# 1. if "@group_found" is falsy AND
# 2. if "@group_created" is truthy,
# 3. "group_found?" returns false and "group_created?" returns true,
# or if it is the reverse, they return the reverse,
# or if neither is the case (i.e., both are falthy are both are truthy),
# this raises ModuleWasFounds::InconsistencyInWasFoundError
#
# In other words, you MUST set either of them truthy to get either true/false
# from either of +group_found?/created?+, avoiding an Exception.
# This is because otherwise, chances are neither of them may have never been set.
#
# @example How to include
# class Article < ApplicationRecord
# include ModuleWasFound # define attr_writers @was_found, @was_created and their questioned-readers.
# define_was_found_for("group") # defined in ModuleWasFound; define #group_found, #group_found? etc
#
# @example How to use the methods (for the default +was_found?+)
# def abc(x)
# self.was_found = nil
# self.was_created = false
# begin
# was_found? rescue was_created?
# rescue ModuleWasFounds::InconsistencyInWasFoundError => er
# warn "You must set either of them truethy."
# end
# self.was_created = true
# was_found? # => false
# was_created? # => true
#
def define_was_found_for(was)
%w(found created).each do |metho|
attr_writer [was, metho].join("_").to_sym # In find_or_create, if an instance is found, this is set.
end
define_method (was+"_found?").to_sym do
it_found = instance_variable_get(("@"+was+"_found").to_sym)
it_created = instance_variable_get(("@"+was+"_created").to_sym)
if it_found && !it_created
true
elsif !it_found && it_created
false
else
raise ModuleWasFounds::InconsistencyInWasFoundError, "(internal) #{was}_found/#{was}_created are either inconsistent or not set. Contact the code developer. self="+inspect
end
end
define_method (was+"_created?").to_sym do
!send(was+"_found?")
end
end
end # module ClassMethods
extend ClassMethods
## instance methods "was_found?". "was_created?" and their respective writers are included (=defined) in default.
define_was_found_for("was")
#################
private
#################
end
# coding: utf-8
require "test_helper"
class ModuleWasFoundTest < ActiveSupport::TestCase
class MyTestModuleWasFound
include ModuleWasFound
define_was_found_for("group")
def this_was_found(found, created, run: :found)
self.was_found = found
self.was_created = created
case run
when :found
was_found?
when :created
was_created?
else
raise ArgumentError, 'wrong arg'
end
end
def this_group_found(found, created, run: :found)
self.group_found = found
self.group_created = created
case run
when :found
group_found?
when :created
group_created?
else
raise ArgumentError, 'wrong arg'
end
end
end
test "was_found/created?" do
obj = MyTestModuleWasFound.new
%i(found created).each do |metho|
assert_raises(ModuleWasFounds::InconsistencyInWasFoundError){
obj.this_was_found(nil, nil, run: metho) }
assert_raises(ModuleWasFounds::InconsistencyInWasFoundError){
obj.this_was_found(false, false, run: metho) }
assert_raises(ModuleWasFounds::InconsistencyInWasFoundError, "failed in #{metho.inspect}"){
obj.this_was_found("ab", "cd", run: metho) }
end
assert obj.this_was_found("a", nil, run: :found)
refute obj.this_was_found(nil, "a", run: :found)
assert obj.this_was_found(nil, "a", run: :created)
refute obj.this_was_found("a", nil, run: :created)
end
test "group_found/created?" do
obj = MyTestModuleWasFound.new
%i(found created).each do |metho|
assert_raises(ModuleWasFounds::InconsistencyInWasFoundError){
obj.this_group_found(nil, nil, run: metho) }
assert_raises(ModuleWasFounds::InconsistencyInWasFoundError){
obj.this_group_found(false, false, run: metho) }
assert_raises(ModuleWasFounds::InconsistencyInWasFoundError, "failed in #{metho.inspect}"){
obj.this_group_found("ab", "cd", run: metho) }
end
assert obj.this_group_found("a", nil, run: :found)
refute obj.this_group_found(nil, "a", run: :found)
assert obj.this_group_found(nil, "a", run: :created)
refute obj.this_group_found("a", nil, run: :created)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment