Last active
May 1, 2025 21:25
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module ModuleWasFounds | |
class InconsistencyInWasFoundError < StandardError # ModuleWasFounds::InconsistencyInWasFoundError | |
## Error in inconsistency in ModuleWasFound#was_found? and ModuleWasFound#was_created? | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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