Repository: pawurb/smart_init
Branch: main
Commit: 915c50550a7f
Files: 14
Total size: 19.8 KB
Directory structure:
gitextract_5m36g2_7/
├── .github/
│ └── workflows/
│ └── ci.yml
├── .gitignore
├── Gemfile
├── LICENSE.txt
├── README.md
├── Rakefile
├── lib/
│ ├── smart_init/
│ │ ├── main.rb
│ │ └── version.rb
│ └── smart_init.rb
├── smart_init.gemspec
└── test/
├── test_hash_api.rb
├── test_hash_public_accessors.rb
├── test_hash_public_mixed.rb
└── test_hash_public_readers.rb
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/ci.yml
================================================
name: Ruby CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
ruby-version: ['3.4', '3.3', '3.2', '3.1', '3.0', '2.7']
steps:
- uses: actions/checkout@v3
- name: Set up Ruby ${{ matrix.ruby-version }}
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby-version }}
- name: Setup dependencies
run: |
gem install bundler -v 2.4.22
sudo apt-get update --allow-releaseinfo-change
bundle config set --local path 'vendor/bundle'
bundle install
- name: Run tests
run: |
bundle exec rake test
================================================
FILE: .gitignore
================================================
Gemfile.lock
.ruby-version
pkg/
*.gem
coverage/
.byebug_history
================================================
FILE: Gemfile
================================================
source "https://rubygems.org"
gemspec
================================================
FILE: LICENSE.txt
================================================
Copyright (c) 2021 Paweł Urbanek
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: README.md
================================================
# Smart Init - Simple service objects in Ruby [](https://badge.fury.io/rb/smart_init) [](https://github.com/pawurb/smart_init/actions)
Do you find yourself writing a lot of boilerplate code like this?
```ruby
def initialize(network_provider, api_token)
@network_provider = network_provider
@api_token = api_token
end
def self.call(network_provider, api_token)
new(network_provider, api_token).call
end
```
This gem provides a simple DSL for getting rid of it. It offers an alternative to using `Struct.new` which does not check for number of parameters provided in initializer, exposes getters and instantiates unecessary class instances.
**Smart Init** offers a unified API convention for stateless service objects, accepting values in initializer and exposing one public class method `call` which instantiates new objects and accepts arguments passed to initializer.
Check out [this blog post](https://pawelurbanek.com/2018/02/12/ruby-on-rails-service-objects-and-testing-in-isolation/) for my reasoning behind this approach to service object pattern.
## Installation
In your Gemfile
```ruby
gem 'smart_init'
```
## API
You can use it either by extending a module:
```ruby
require 'smart_init'
class ApiClient
extend SmartInit
initialize_with :network_provider, :api_token
end
```
or subclassing:
```ruby
class ApiClient < SmartInit::Base
initialize_with :network_provider, :api_token
end
```
Now you can just:
```ruby
object = ApiClient.new(network_provider: Faraday.new, api_token: 'secret_token')
# <ApiClient:0x007fa16684ec20 @network_provider=Faraday<...>, @api_token="secret_token">
```
If you omit a required attribute an `ArgumentError` will be thrown:
```ruby
client = ApiClient.new(network_provider: Faraday.new)
# ArgumentError (missing required attribute api_token)
```
### Making the object callable
You can use the `is_callable` method:
```ruby
class Calculator < SmartInit::Base
initialize_with :data
is_callable
def call
...
result
end
end
Calculator.call(data: data) => result
```
Optionally you can customize a callable method name:
```ruby
class Routine < SmartInit::Base
initialize_with :params
is_callable method_name: :run!
def run!
...
end
end
Routine.run!(params: params)
```
### Default arguments
You can use hash based, default argument values:
```ruby
class Adder < SmartInit::Base
initialize_with :num_a, num_b: 2
is_callable
def call
num_a + num_b
end
end
Adder.call(num_a: 2) => 4
Adder.call(num_a: 2, num_b: 3) => 5
```
### Readers access
Contrary to using Struct, by default the reader methods are not publicly exposed:
```ruby
client = ApiClient.new(network_provider: Faraday.new, api_token: 'secret_token')
client.api_token => # NoMethodError (private method `api_token' called for #<ApiClient:0x000..>)
```
Optionally you can make all or subset of readers public using the `public_readers` config option. It accepts `true` or an array of method names as an argument.
```ruby
class PublicApiClient < SmartInit::Base
initialize_with :network_provider, :api_token, public_readers: true
end
client = PublicApiClient.new(network_provider: Faraday.new, api_token: 'secret_token')
client.network_provider => #<Faraday::Connection:0x000...>
client.api_token => 'secret_token'
```
```ruby
class SemiPublicApiClient < SmartInit::Base
initialize_with :network_provider, :api_token, public_readers: [:network_provider]
end
client = SemiPublicApiClient.new(network_provider: Faraday.new, api_token: 'secret_token')
client.network_provider => #<Faraday::Connection:0x000...>
client.api_token => 'secret_token' => # NoMethodError (private method `api_token' called for #<SemiPublicApiClient:0x000...>)
```
### Accessors access
Similarly, this is how it would look if you tried to use a writer method:
```ruby
client = ApiClient.new(network_provider: Faraday.new, api_token: 'secret_token')
client.api_token = 'new_token' => # NoMethodError (private method `api_token=' called for #<ApiClient:0x000..>)
```
Optionally you can make all or subset of accessors public using the `public_accessors` config option. It accepts `true` or an array of method names as an argument. This will provide both reader and writer methods publicly.
```ruby
class PublicApiClient < SmartInit::Base
initialize_with :network_provider, :api_token, public_accessors: true
end
client = PublicApiClient.new(network_provider: Faraday.new, api_token: 'secret_token')
client.network_provider => #<Faraday::Connection:0x000...>
client.network_provider = Typhoeus::Request.new(...) => #<Typhoeus::Request:0x000...>
client.api_token => 'secret_token'
client.api_token = 'new_token' => 'new_token'
```
```ruby
class SemiPublicApiClient < SmartInit::Base
initialize_with :network_provider, :api_token, public_accessors: [:network_provider]
end
client = SemiPublicApiClient.new(network_provider: Faraday.new, api_token: 'secret_token')
client.network_provider => #<Faraday::Connection:0x000...>
client.network_provider = Typhoeus::Request.new(...) => #<Typhoeus::Request:0x000...>
client.api_token => # NoMethodError (private method `api_token' called for #<SemiPublicApiClient:0x000...>)
client.api_token = 'new_token' => # NoMethodError (undefined method `api_token=' called for #<SemiPublicApiClient:0x000...>)
```
Finally, you can mix them together like this:
```ruby
class PublicReadersSemiPublicAccessorsApiClient < SmartInit::Base
initialize_with :network_provider, :api_token, :timeout,
public_readers: true, public_accessors: [:network_provider]
end
client = PublicReadersSemiPublicAccessorsApiClient.new(
network_provider: Faraday.new, api_token: 'secret_token', timeout_length: 100
)
client.network_provider => #<Faraday::Connection:0x000...>
client.network_provider = Typhoeus::Request.new(...) => #<Typhoeus::Request:0x000...>
client.api_token => 'secret_token'
client.api_token = 'new_token' => # NoMethodError (undefined method `api_token=' called for #<SemiPublicApiClient:0x000...>)
client.timeout_length => 100
client.timeout_length = 150 => # NoMethodError (undefined method `timeout_length=' called for #<SemiPublicApiClient:0x000...>)
```
```ruby
class SemiPublicReadersSemiPublicAccessorsApiClient < SmartInit::Base
initialize_with :network_provider, :api_token, :timeout,
public_readers: [:timeout], public_accessors: [:network_provider]
end
client = SemiPublicReadersSemiPublicAccessorsApiClient.new(
network_provider: Faraday.new, api_token: 'secret_token', timeout_length: 100
)
client.network_provider => #<Faraday::Connection:0x000...>
client.network_provider = Typhoeus::Request.new(...) => #<Typhoeus::Request:0x000...>
client.api_token => # NoMethodError (private method `api_token' called for #<SemiPublicReadersSemiPublicAccessorsApiClient:0x000...>)
client.api_token = 'new_token' => # NoMethodError (undefined method `api_token=' called for #<SemiPublicReadersSemiPublicAccessorsApiClient:0x000...>)
client.timeout_length => 100
client.timeout_length = 150 => # NoMethodError (undefined method `timeout_length=' called for #<SemiPublicReadersSemiPublicAccessorsApiClient:0x000...>)
```
================================================
FILE: Rakefile
================================================
require "bundler/gem_tasks"
require "rake/testtask"
Rake::TestTask.new do |t|
t.libs << "test"
end
desc "Run tests"
task :default => :test
================================================
FILE: lib/smart_init/main.rb
================================================
# frozen_string_literal: true
module SmartInit
def is_callable(opts = {})
method_name = if name_from_opts = opts[:method_name]
name_from_opts.to_sym
else
:call
end
define_singleton_method method_name do |**parameters|
new(**parameters).public_send(method_name)
end
end
def initialize_with_hash(*required_attrs, **default_values_and_opts)
public_readers = default_values_and_opts.delete(:public_readers) || []
public_accessors = default_values_and_opts.delete(:public_accessors) || []
if public_readers == true || public_accessors == true
public_readers = required_attrs + default_values_and_opts.keys
public_accessors = required_attrs + default_values_and_opts.keys if public_accessors == true
else
public_readers += public_accessors
end
define_method :initialize do |**parameters|
required_attrs.each do |required_attr|
unless parameters.has_key?(required_attr)
raise ArgumentError, "missing required attribute #{required_attr}"
end
end
parameters.keys.each do |param|
if !(required_attrs + [:public_readers, :public_accessors]).include?(param) && !default_values_and_opts.keys.include?(param)
raise ArgumentError, "invalid attribute '#{param}'"
end
end
(required_attrs + default_values_and_opts.keys).each do |attribute|
value = if parameters.has_key?(attribute)
parameters.fetch(attribute)
else
default_values_and_opts[attribute]
end
instance_variable_set("@#{attribute}", value)
end
end
instance_eval do
all_readers = (required_attrs + default_values_and_opts.keys)
attr_reader(*all_readers)
(all_readers - public_readers).each do |reader|
private reader
end
attr_writer(*public_accessors)
end
end
alias initialize_with initialize_with_hash
end
class SmartInit::Base
extend SmartInit
end
================================================
FILE: lib/smart_init/version.rb
================================================
# frozen_string_literal: true
module SmartInit
VERSION = "5.1.0"
end
================================================
FILE: lib/smart_init.rb
================================================
# frozen_string_literal: true
require "smart_init/main"
module SmartInit
end
================================================
FILE: smart_init.gemspec
================================================
# -*- encoding: utf-8 -*-
lib = File.expand_path("../lib", __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "smart_init/version"
Gem::Specification.new do |s|
s.name = "smart_init"
s.version = SmartInit::VERSION
s.authors = ["pawurb"]
s.email = ["p.urbanek89@gmail.com"]
s.summary = %q{ Remove Ruby initializer boilerplate code }
s.description = %q{ A smart DSL for ruby initializers boilerplate }
s.homepage = "http://github.com/pawurb/smart_init"
s.files = `git ls-files`.split("\n")
s.test_files = s.files.grep(%r{^(test)/})
s.require_paths = ["lib"]
s.license = "MIT"
s.add_development_dependency "rake"
s.add_development_dependency "byebug"
s.add_development_dependency "dbg-rb"
s.add_development_dependency "test-unit"
s.add_development_dependency "rufo"
if s.respond_to?(:metadata=)
s.metadata = { "rubygems_mfa_required" => "true" }
end
end
================================================
FILE: test/test_hash_api.rb
================================================
# frozen_string_literal: true
require "test/unit"
require_relative "../lib/smart_init/main"
class TestService
extend SmartInit
initialize_with :attribute_1, :attribute_2
is_callable
def call
[attribute_1, attribute_2]
end
end
class TestServiceDefaults
extend SmartInit
initialize_with :attribute_1, attribute_2: "default_value_2", attribute_3: "default_value_3"
is_callable
def call
[attribute_1, attribute_2, attribute_3]
end
end
class TestServiceAllDefaults
extend SmartInit
initialize_with attribute_1: "default_value_1", attribute_2: "default_value_2", attribute_3: "default_value_3"
is_callable
def call
[attribute_1, attribute_2, attribute_3]
end
end
class TestHashIntegerDefaults
extend SmartInit
initialize_with :attribute_1, attribute_2: 2
is_callable
def call
[attribute_1, attribute_2]
end
end
class HashApiTest < Test::Unit::TestCase
def test_keywords
assert_equal TestService.call(attribute_1: "a", attribute_2: "b"), ["a", "b"]
assert_raise ArgumentError do
TestService.new(
attribute_1: "a",
)
end
end
def test_keywords_defaults
assert_equal TestServiceDefaults.call(attribute_1: "a"), ["a", "default_value_2", "default_value_3"]
assert_equal TestServiceDefaults.call(attribute_1: "a", attribute_2: "b"), ["a", "b", "default_value_3"]
end
def test_private_readers
service = TestServiceDefaults.new(attribute_1: "a")
error = assert_raise NoMethodError do
service.attribute_2
end
assert_match("private method", error.message)
end
def test_integer_defaults
assert_equal TestHashIntegerDefaults.call(attribute_1: 1), [1, 2]
end
def test_missing_attributes
assert_raise ArgumentError do
TestService.call(attribute_1: "a", invalid_attribute: "b")
end
end
def test_invalid_input
assert_raise ArgumentError do
TestService.call("invalid_input here")
end
end
def test_all_defaults
assert_equal TestServiceAllDefaults.call, ["default_value_1", "default_value_2", "default_value_3"]
end
def test_falsey_values
assert_equal TestService.call(attribute_1: false, attribute_2: nil), [false, nil]
end
def test_invalid_keywords
assert_raise ArgumentError do
TestService.call(attribute_1: "a", attribute_2: "b", invalid_attribute: "c")
end
end
end
================================================
FILE: test/test_hash_public_accessors.rb
================================================
# frozen_string_literal: true
require "test/unit"
require_relative "../lib/smart_init/main"
class TestAllPublicAccessors
extend SmartInit
initialize_with :attribute_1, :attribute_2, public_accessors: true
is_callable
def call
[attribute_1, attribute_2]
end
end
class TestSomePublicAccessors
extend SmartInit
initialize_with :attribute_1, :attribute_2, public_accessors: [:attribute_1]
is_callable
def call
[attribute_1, attribute_2]
end
end
class TestDefaultPublicAccessors
extend SmartInit
initialize_with :attribute_1, attribute_2: 2, public_accessors: [:attribute_2]
def call
[attribute_1, attribute_2]
end
end
class HashApiPublicTestAccessors < Test::Unit::TestCase
def test_all_public
service = TestAllPublicAccessors.new(attribute_1: "a", attribute_2: "b")
assert_nothing_raised do
service.attribute_1 = "c"
service.attribute_2 = "d"
end
assert_equal service.attribute_1, "c"
assert_equal service.attribute_2, "d"
end
def test_some_public
service = TestSomePublicAccessors.new(attribute_1: "a", attribute_2: "b")
assert_nothing_raised do
service.attribute_1 = "c"
end
assert_equal service.attribute_1, "c"
assert_raise NoMethodError do
service.attribute_2
end
assert_raise NoMethodError do
service.attribute_2 = "d"
end
end
def test_default_public
service = TestDefaultPublicAccessors.new(attribute_1: "a")
assert_nothing_raised do
service.attribute_2 = 3
end
assert_equal service.attribute_2, 3
assert_raise NoMethodError do
service.attribute_1 = "b"
end
assert_raise NoMethodError do
service.attribute_1
end
end
end
================================================
FILE: test/test_hash_public_mixed.rb
================================================
# frozen_string_literal: true
require "test/unit"
require_relative "../lib/smart_init/main"
class TestSomePublicMixed
extend SmartInit
initialize_with :attribute_1, :attribute_2, :attribute_3, :attribute_4,
public_readers: [:attribute_1],
public_accessors: [:attribute_2, :attribute_3]
is_callable
def call
[attribute_1, attribute_2, attribute_3, attribute_4]
end
end
class TestAllReadersSomeAccessorsPublic
extend SmartInit
initialize_with :attribute_1, :attribute_2, public_readers: true, public_accessors: [:attribute_2]
def call
[attribute_1, attribute_2]
end
end
class HashApiPublicTest < Test::Unit::TestCase
def test_readers_some_public_mixed
service = TestSomePublicMixed.new(
attribute_1: "a", attribute_2: "b",
attribute_3: "c", attribute_4: "d",
)
assert_nothing_raised do
service.attribute_1
service.attribute_2
service.attribute_3
end
assert_raise NoMethodError do
service.attribute_4
end
end
def test_writers_some_public_mixed
service = TestSomePublicMixed.new(
attribute_1: "a", attribute_2: "b",
attribute_3: "c", attribute_4: "d",
)
assert_nothing_raised do
service.attribute_2 = "e"
service.attribute_3 = "f"
end
assert_equal service.attribute_2, "e"
assert_equal service.attribute_3, "f"
assert_raise NoMethodError do
service.attribute_4 = "g"
end
end
def test_readers_all_readers_some_accessors_public
service = TestAllReadersSomeAccessorsPublic.new(
attribute_1: "a", attribute_2: "b",
)
assert_nothing_raised do
service.attribute_1
service.attribute_2
end
end
def test_writers_all_readers_some_accessors_public
service = TestAllReadersSomeAccessorsPublic.new(
attribute_1: "a", attribute_2: "b",
)
assert_raise NoMethodError do
service.attribute_1 = "c"
end
assert_nothing_raised do
service.attribute_2 = "d"
end
assert_equal service.attribute_2, "d"
end
end
================================================
FILE: test/test_hash_public_readers.rb
================================================
# frozen_string_literal: true
require "test/unit"
require_relative "../lib/smart_init/main"
class TestAllPublic
extend SmartInit
initialize_with :attribute_1, :attribute_2, public_readers: true
is_callable
def call
[attribute_1, attribute_2]
end
end
class TestSomePublic
extend SmartInit
initialize_with :attribute_1, :attribute_2, public_readers: [:attribute_1]
is_callable
def call
[attribute_1, attribute_2]
end
end
class TestDefaultPublic
extend SmartInit
initialize_with :attribute_1, attribute_2: 2, public_readers: [:attribute_2]
def call
[attribute_1, attribute_2]
end
end
class TestDefaultAllPublic
extend SmartInit
initialize_with :attribute_1, attribute_2: 2, public_readers: true
def call
[attribute_1, attribute_2]
end
end
class HashApiPublicTest < Test::Unit::TestCase
def test_all_public
service = TestAllPublic.new(attribute_1: "a", attribute_2: "b")
assert_equal service.attribute_1, "a"
assert_equal service.attribute_2, "b"
end
def test_some_public
service = TestSomePublic.new(attribute_1: "a", attribute_2: "b")
assert_equal service.attribute_1, "a"
assert_raise NoMethodError do
service.attribute_2
end
end
def test_default_public
service = TestDefaultPublic.new(attribute_1: "a")
assert_equal service.attribute_2, 2
assert_raise NoMethodError do
service.attribute_1
end
end
def test_default_all_public
service = TestDefaultAllPublic.new(attribute_1: "a")
assert_equal service.attribute_1, "a"
assert_equal service.attribute_2, 2
end
end
gitextract_5m36g2_7/
├── .github/
│ └── workflows/
│ └── ci.yml
├── .gitignore
├── Gemfile
├── LICENSE.txt
├── README.md
├── Rakefile
├── lib/
│ ├── smart_init/
│ │ ├── main.rb
│ │ └── version.rb
│ └── smart_init.rb
├── smart_init.gemspec
└── test/
├── test_hash_api.rb
├── test_hash_public_accessors.rb
├── test_hash_public_mixed.rb
└── test_hash_public_readers.rb
SYMBOL INDEX (56 symbols across 7 files)
FILE: lib/smart_init.rb
type SmartInit (line 5) | module SmartInit
FILE: lib/smart_init/main.rb
type SmartInit (line 3) | module SmartInit
function is_callable (line 4) | def is_callable(opts = {})
function initialize_with_hash (line 16) | def initialize_with_hash(*required_attrs, **default_values_and_opts)
class SmartInit::Base (line 63) | class SmartInit::Base
FILE: lib/smart_init/version.rb
type SmartInit (line 3) | module SmartInit
FILE: test/test_hash_api.rb
class TestService (line 6) | class TestService
method call (line 11) | def call
class TestServiceDefaults (line 16) | class TestServiceDefaults
method call (line 21) | def call
class TestServiceAllDefaults (line 26) | class TestServiceAllDefaults
method call (line 31) | def call
class TestHashIntegerDefaults (line 36) | class TestHashIntegerDefaults
method call (line 41) | def call
class HashApiTest (line 46) | class HashApiTest < Test::Unit::TestCase
method test_keywords (line 47) | def test_keywords
method test_keywords_defaults (line 57) | def test_keywords_defaults
method test_private_readers (line 62) | def test_private_readers
method test_integer_defaults (line 71) | def test_integer_defaults
method test_missing_attributes (line 75) | def test_missing_attributes
method test_invalid_input (line 81) | def test_invalid_input
method test_all_defaults (line 87) | def test_all_defaults
method test_falsey_values (line 91) | def test_falsey_values
method test_invalid_keywords (line 95) | def test_invalid_keywords
FILE: test/test_hash_public_accessors.rb
class TestAllPublicAccessors (line 6) | class TestAllPublicAccessors
method call (line 11) | def call
class TestSomePublicAccessors (line 16) | class TestSomePublicAccessors
method call (line 21) | def call
class TestDefaultPublicAccessors (line 26) | class TestDefaultPublicAccessors
method call (line 30) | def call
class HashApiPublicTestAccessors (line 35) | class HashApiPublicTestAccessors < Test::Unit::TestCase
method test_all_public (line 36) | def test_all_public
method test_some_public (line 46) | def test_some_public
method test_default_public (line 60) | def test_default_public
FILE: test/test_hash_public_mixed.rb
class TestSomePublicMixed (line 6) | class TestSomePublicMixed
method call (line 13) | def call
class TestAllReadersSomeAccessorsPublic (line 18) | class TestAllReadersSomeAccessorsPublic
method call (line 22) | def call
class HashApiPublicTest (line 27) | class HashApiPublicTest < Test::Unit::TestCase
method test_readers_some_public_mixed (line 28) | def test_readers_some_public_mixed
method test_writers_some_public_mixed (line 43) | def test_writers_some_public_mixed
method test_readers_all_readers_some_accessors_public (line 59) | def test_readers_all_readers_some_accessors_public
method test_writers_all_readers_some_accessors_public (line 69) | def test_writers_all_readers_some_accessors_public
FILE: test/test_hash_public_readers.rb
class TestAllPublic (line 6) | class TestAllPublic
method call (line 11) | def call
class TestSomePublic (line 16) | class TestSomePublic
method call (line 21) | def call
class TestDefaultPublic (line 26) | class TestDefaultPublic
method call (line 30) | def call
class TestDefaultAllPublic (line 35) | class TestDefaultAllPublic
method call (line 39) | def call
class HashApiPublicTest (line 44) | class HashApiPublicTest < Test::Unit::TestCase
method test_all_public (line 45) | def test_all_public
method test_some_public (line 51) | def test_some_public
method test_default_public (line 59) | def test_default_public
method test_default_all_public (line 68) | def test_default_all_public
Condensed preview — 14 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (22K chars).
[
{
"path": ".github/workflows/ci.yml",
"chars": 741,
"preview": "name: Ruby CI\n\non:\n push:\n branches: [ main ]\n pull_request:\n branches: [ main ]\n\njobs:\n test:\n runs-on: ubu"
},
{
"path": ".gitignore",
"chars": 65,
"preview": "Gemfile.lock\n.ruby-version\npkg/\n*.gem\ncoverage/\n.byebug_history\n\n"
},
{
"path": "Gemfile",
"chars": 39,
"preview": "source \"https://rubygems.org\"\n\ngemspec\n"
},
{
"path": "LICENSE.txt",
"chars": 1070,
"preview": "Copyright (c) 2021 Paweł Urbanek\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na c"
},
{
"path": "README.md",
"chars": 7344,
"preview": "# Smart Init - Simple service objects in Ruby [](https://badge.fu"
},
{
"path": "Rakefile",
"chars": 143,
"preview": "require \"bundler/gem_tasks\"\nrequire \"rake/testtask\"\n\nRake::TestTask.new do |t|\n t.libs << \"test\"\nend\n\ndesc \"Run tests\"\n"
},
{
"path": "lib/smart_init/main.rb",
"chars": 2000,
"preview": "# frozen_string_literal: true\n\nmodule SmartInit\n def is_callable(opts = {})\n method_name = if name_from_opts = opts["
},
{
"path": "lib/smart_init/version.rb",
"chars": 72,
"preview": "# frozen_string_literal: true\n\nmodule SmartInit\n VERSION = \"5.1.0\"\nend\n"
},
{
"path": "lib/smart_init.rb",
"chars": 79,
"preview": "# frozen_string_literal: true\n\nrequire \"smart_init/main\"\n\nmodule SmartInit\nend\n"
},
{
"path": "smart_init.gemspec",
"chars": 916,
"preview": "# -*- encoding: utf-8 -*-\nlib = File.expand_path(\"../lib\", __FILE__)\n$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?("
},
{
"path": "test/test_hash_api.rb",
"chars": 2372,
"preview": "# frozen_string_literal: true\n\nrequire \"test/unit\"\nrequire_relative \"../lib/smart_init/main\"\n\nclass TestService\n extend"
},
{
"path": "test/test_hash_public_accessors.rb",
"chars": 1718,
"preview": "# frozen_string_literal: true\n\nrequire \"test/unit\"\nrequire_relative \"../lib/smart_init/main\"\n\nclass TestAllPublicAccesso"
},
{
"path": "test/test_hash_public_mixed.rb",
"chars": 2070,
"preview": "# frozen_string_literal: true\n\nrequire \"test/unit\"\nrequire_relative \"../lib/smart_init/main\"\n\nclass TestSomePublicMixed\n"
},
{
"path": "test/test_hash_public_readers.rb",
"chars": 1610,
"preview": "# frozen_string_literal: true\n\nrequire \"test/unit\"\nrequire_relative \"../lib/smart_init/main\"\n\nclass TestAllPublic\n exte"
}
]
About this extraction
This page contains the full source code of the pawurb/smart_init GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 14 files (19.8 KB), approximately 5.6k tokens, and a symbol index with 56 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.