├── .editorconfig ├── .gitattributes ├── .github ├── assets │ └── 459060.gif └── workflows │ ├── publishing.yml │ └── testing.yml ├── .gitignore ├── .mailmap ├── .perlcriticrc ├── .perltidyrc ├── .replyrc ├── CHANGES ├── CHANGES.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── MANIFEST.SKIP ├── META.json ├── META.yml ├── Makefile.PL ├── README ├── README.md ├── RELEASE.md ├── VERSION ├── bin └── vns ├── cpanfile ├── dist.ini ├── examples ├── box.pl ├── cli.pl ├── count.pl ├── data.pl ├── date.pl ├── deduce.pl ├── dump.pl ├── equality.pl ├── error.pl ├── gather.pl ├── ipc.pl ├── json.pl ├── mappable.pl ├── match.pl ├── ones.pl ├── os.pl ├── path.pl ├── processes.pl ├── random.pl ├── yaml.pl └── zeros.pl ├── lib ├── Venus.pm ├── Venus.pod └── Venus │ ├── Args.pm │ ├── Args.pod │ ├── Array.pm │ ├── Array.pod │ ├── Assert.pm │ ├── Assert.pod │ ├── Atom.pm │ ├── Atom.pod │ ├── Boolean.pm │ ├── Boolean.pod │ ├── Box.pm │ ├── Box.pod │ ├── Check.pm │ ├── Check.pod │ ├── Class.pm │ ├── Class.pod │ ├── Cli.pm │ ├── Cli.pod │ ├── Code.pm │ ├── Code.pod │ ├── Coercion.pm │ ├── Coercion.pod │ ├── Config.pm │ ├── Config.pod │ ├── Constraint.pm │ ├── Constraint.pod │ ├── Container.pm │ ├── Container.pod │ ├── Core.pm │ ├── Core.pod │ ├── Core │ ├── Class.pm │ ├── Class.pod │ ├── Mixin.pm │ ├── Mixin.pod │ ├── Role.pm │ └── Role.pod │ ├── Data.pm │ ├── Data.pod │ ├── Date.pm │ ├── Date.pod │ ├── Dump.pm │ ├── Dump.pod │ ├── Enum.pm │ ├── Enum.pod │ ├── Error.pm │ ├── Error.pod │ ├── False.pm │ ├── False.pod │ ├── Fault.pm │ ├── Fault.pod │ ├── Float.pm │ ├── Float.pod │ ├── Future.pm │ ├── Future.pod │ ├── Gather.pm │ ├── Gather.pod │ ├── Hash.pm │ ├── Hash.pod │ ├── Json.pm │ ├── Json.pod │ ├── Kind.pm │ ├── Kind.pod │ ├── Kind │ ├── Utility.pm │ ├── Utility.pod │ ├── Value.pm │ └── Value.pod │ ├── Log.pm │ ├── Log.pod │ ├── Match.pm │ ├── Match.pod │ ├── Meta.pm │ ├── Meta.pod │ ├── Mixin.pm │ ├── Mixin.pod │ ├── Name.pm │ ├── Name.pod │ ├── Number.pm │ ├── Number.pod │ ├── Opts.pm │ ├── Opts.pod │ ├── Os.pm │ ├── Os.pod │ ├── Path.pm │ ├── Path.pod │ ├── Process.pm │ ├── Process.pod │ ├── Prototype.pm │ ├── Prototype.pod │ ├── Random.pm │ ├── Random.pod │ ├── Regexp.pm │ ├── Regexp.pod │ ├── Replace.pm │ ├── Replace.pod │ ├── Role.pm │ ├── Role.pod │ ├── Role │ ├── Accessible.pm │ ├── Accessible.pod │ ├── Assertable.pm │ ├── Assertable.pod │ ├── Boxable.pm │ ├── Boxable.pod │ ├── Buildable.pm │ ├── Buildable.pod │ ├── Catchable.pm │ ├── Catchable.pod │ ├── Coercible.pm │ ├── Coercible.pod │ ├── Comparable.pm │ ├── Comparable.pod │ ├── Defaultable.pm │ ├── Defaultable.pod │ ├── Deferrable.pm │ ├── Deferrable.pod │ ├── Digestable.pm │ ├── Digestable.pod │ ├── Doable.pm │ ├── Doable.pod │ ├── Dumpable.pm │ ├── Dumpable.pod │ ├── Explainable.pm │ ├── Explainable.pod │ ├── Makeable.pm │ ├── Makeable.pod │ ├── Mappable.pm │ ├── Mappable.pod │ ├── Matchable.pm │ ├── Matchable.pod │ ├── Mockable.pm │ ├── Mockable.pod │ ├── Optional.pm │ ├── Optional.pod │ ├── Patchable.pm │ ├── Patchable.pod │ ├── Pluggable.pm │ ├── Pluggable.pod │ ├── Printable.pm │ ├── Printable.pod │ ├── Proxyable.pm │ ├── Proxyable.pod │ ├── Reflectable.pm │ ├── Reflectable.pod │ ├── Rejectable.pm │ ├── Rejectable.pod │ ├── Serializable.pm │ ├── Serializable.pod │ ├── Stashable.pm │ ├── Stashable.pod │ ├── Subscribable.pm │ ├── Subscribable.pod │ ├── Superable.pm │ ├── Superable.pod │ ├── Testable.pm │ ├── Testable.pod │ ├── Throwable.pm │ ├── Throwable.pod │ ├── Tryable.pm │ ├── Tryable.pod │ ├── Unacceptable.pm │ ├── Unacceptable.pod │ ├── Unpackable.pm │ ├── Unpackable.pod │ ├── Valuable.pm │ └── Valuable.pod │ ├── Run.pm │ ├── Run.pod │ ├── Scalar.pm │ ├── Scalar.pod │ ├── Schema.pm │ ├── Schema.pod │ ├── Sealed.pm │ ├── Sealed.pod │ ├── Search.pm │ ├── Search.pod │ ├── Space.pm │ ├── Space.pod │ ├── String.pm │ ├── String.pod │ ├── Task.pm │ ├── Task.pod │ ├── Template.pm │ ├── Template.pod │ ├── Test.pm │ ├── Test.pod │ ├── Throw.pm │ ├── Throw.pod │ ├── True.pm │ ├── True.pod │ ├── Try.pm │ ├── Try.pod │ ├── Type.pm │ ├── Type.pod │ ├── Undef.pm │ ├── Undef.pod │ ├── Unpack.pm │ ├── Unpack.pod │ ├── Vars.pm │ ├── Vars.pod │ ├── Yaml.pm │ └── Yaml.pod ├── shim └── vns ├── t ├── Venus.t ├── Venus_Args.t ├── Venus_Array.t ├── Venus_Assert.t ├── Venus_Atom.t ├── Venus_Boolean.t ├── Venus_Box.t ├── Venus_Check.t ├── Venus_Class.t ├── Venus_Cli.t ├── Venus_Code.t ├── Venus_Coercion.t ├── Venus_Config.t ├── Venus_Constraint.t ├── Venus_Container.t ├── Venus_Core.t ├── Venus_Core_Class.t ├── Venus_Core_Mixin.t ├── Venus_Core_Role.t ├── Venus_Data.t ├── Venus_Date.t ├── Venus_Dump.t ├── Venus_Enum.t ├── Venus_Error.t ├── Venus_False.t ├── Venus_Fault.t ├── Venus_Float.t ├── Venus_Future.t ├── Venus_Gather.t ├── Venus_Hash.t ├── Venus_Json.t ├── Venus_Kind.t ├── Venus_Kind_Utility.t ├── Venus_Kind_Value.t ├── Venus_Log.t ├── Venus_Match.t ├── Venus_Meta.t ├── Venus_Mixin.t ├── Venus_Name.t ├── Venus_Number.t ├── Venus_Opts.t ├── Venus_Os.t ├── Venus_Path.t ├── Venus_Process.t ├── Venus_Prototype.t ├── Venus_Random.t ├── Venus_Regexp.t ├── Venus_Replace.t ├── Venus_Role.t ├── Venus_Role_Accessible.t ├── Venus_Role_Assertable.t ├── Venus_Role_Boxable.t ├── Venus_Role_Buildable.t ├── Venus_Role_Catchable.t ├── Venus_Role_Coercible.t ├── Venus_Role_Comparable.t ├── Venus_Role_Defaultable.t ├── Venus_Role_Deferrable.t ├── Venus_Role_Digestable.t ├── Venus_Role_Doable.t ├── Venus_Role_Dumpable.t ├── Venus_Role_Explainable.t ├── Venus_Role_Makeable.t ├── Venus_Role_Mappable.t ├── Venus_Role_Matchable.t ├── Venus_Role_Mockable.t ├── Venus_Role_Optional.t ├── Venus_Role_Patchable.t ├── Venus_Role_Pluggable.t ├── Venus_Role_Printable.t ├── Venus_Role_Proxyable.t ├── Venus_Role_Reflectable.t ├── Venus_Role_Rejectable.t ├── Venus_Role_Serializable.t ├── Venus_Role_Stashable.t ├── Venus_Role_Subscribable.t ├── Venus_Role_Superable.t ├── Venus_Role_Testable.t ├── Venus_Role_Throwable.t ├── Venus_Role_Tryable.t ├── Venus_Role_Unacceptable.t ├── Venus_Role_Unpackable.t ├── Venus_Role_Valuable.t ├── Venus_Run.t ├── Venus_Scalar.t ├── Venus_Schema.t ├── Venus_Sealed.t ├── Venus_Search.t ├── Venus_Space.t ├── Venus_String.t ├── Venus_Task.t ├── Venus_Template.t ├── Venus_Test.t ├── Venus_Throw.t ├── Venus_True.t ├── Venus_Try.t ├── Venus_Type.t ├── Venus_Undef.t ├── Venus_Unpack.t ├── Venus_Vars.t ├── Venus_Yaml.t ├── conf │ ├── .vns.pl │ ├── asks.perl │ ├── edit.perl │ ├── flow.perl │ ├── from.perl │ ├── func.perl │ ├── help.perl │ ├── psql.perl │ ├── read.json │ ├── read.perl │ ├── read.yaml │ ├── when.perl │ ├── with.perl │ ├── write.json │ ├── write.perl │ └── write.yaml ├── data │ ├── moon │ ├── planets │ │ ├── ceres │ │ ├── earth │ │ ├── eris │ │ ├── haumea │ │ ├── jupiter │ │ ├── makemake │ │ ├── mars │ │ ├── mercury │ │ ├── neptune │ │ ├── planet9 │ │ ├── pluto │ │ ├── saturn │ │ ├── uranus │ │ └── venus │ ├── sections │ └── sun └── path │ ├── 001 │ ├── etc │ └── dump.pl │ ├── pod │ ├── example │ └── test │ ├── user │ ├── bin │ │ ├── app3 │ │ ├── app3.exe │ │ └── cmd │ └── local │ │ └── bin │ │ ├── app1 │ │ ├── app2 │ │ ├── app4 │ │ └── cmd │ └── usr │ ├── bin │ ├── app1 │ ├── app2 │ └── cmd │ ├── local │ ├── bin │ │ ├── app4 │ │ └── cmd │ └── sbin │ │ ├── app4 │ │ └── cmd │ └── sbin │ ├── app1 │ ├── app3 │ └── cmd └── wiki ├── _footer.md ├── _sidebar.md ├── content ├── backstory.pod └── preamble.pod ├── home.md ├── info.md ├── roles.md ├── system.md ├── utilities.md └── values.md /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | charset = utf-8 3 | end_of_line = lf 4 | indent_size = 2 5 | indent_style = space 6 | insert_final_newline = false 7 | tab_width = 2 8 | trim_trailing_whitespace = true -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pl linguist-language=Perl 2 | *.pm linguist-language=Perl 3 | *.t linguist-language=Perl 4 | .github/** linguist-documentation 5 | changelog/** linguist-documentation 6 | cpanfiles/** linguist-documentation 7 | dev/** linguist-documentation 8 | examples/** linguist-documentation 9 | plx/** linguist-documentation 10 | shim/** linguist-documentation 11 | -------------------------------------------------------------------------------- /.github/assets/459060.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awncorp/venus/a0c216126c87116a3a5c913e06faffdaa5599c91/.github/assets/459060.gif -------------------------------------------------------------------------------- /.github/workflows/publishing.yml: -------------------------------------------------------------------------------- 1 | name: Publishing 2 | 3 | on: 4 | push: 5 | paths: 6 | - 'wiki/**' 7 | branches: 8 | - master 9 | 10 | jobs: 11 | Publish: 12 | runs-on: ubuntu-latest 13 | container: 14 | image: perl:5.32 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | - name: Publish Wiki 19 | uses: andrew-chen-wang/github-wiki-action@v3 20 | env: 21 | WIKI_DIR: wiki/ 22 | GH_TOKEN: ${{ secrets.REPO_USER_TOKEN }} 23 | GH_MAIL: ${{ secrets.REPO_USER_EMAIL }} 24 | GH_NAME: ${{ secrets.REPO_USER_HANDLE }} 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | !/.github 4 | !/benchmarks 5 | !/bin 6 | !/changelog 7 | !/cpanfiles 8 | !/dev 9 | !/examples 10 | !/lib 11 | !/plx 12 | !/shim 13 | !/t 14 | !/wiki 15 | !/xt 16 | 17 | !CHANGES 18 | !CHANGES.md 19 | !CODE_OF_CONDUCT.md 20 | !CONTRIBUTING.md 21 | !GITHUB.md 22 | !INSTALL 23 | !LICENSE 24 | !MANIFEST 25 | !MANIFEST.SKIP 26 | !META.json 27 | !META.yml 28 | !Makefile.PL 29 | !README 30 | !README.md 31 | !RELEASE.md 32 | !VERSION 33 | !cpanfile 34 | !dist.ini 35 | 36 | !.ctags 37 | !.editorconfig 38 | !.gitattributes 39 | !.gitignore 40 | !.gitlab-ci.yml 41 | !.mailmap 42 | !.perlcriticrc 43 | !.perltidyrc 44 | !.replyrc -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Al Newkirk 2 | Al Newkirk 3 | -------------------------------------------------------------------------------- /.perlcriticrc: -------------------------------------------------------------------------------- 1 | color=1 2 | severity=1 3 | theme=risky + (pbp * security) - cosmetic 4 | verbose=4 5 | exclude=ClassHierarchies NamingConventions RequireTestLabels 6 | 7 | [-Modules::RequireVersionVar] 8 | [-Modules::RequireExplicitPackage] -------------------------------------------------------------------------------- /.perltidyrc: -------------------------------------------------------------------------------- 1 | -pbp # Start with Perl Best Practices 2 | -w # Show all warnings 3 | -iob # Ignore old breakpoints 4 | -l=80 # 80 characters per line 5 | -mbl=2 # No more than 2 blank lines 6 | -i=2 # Indentation is 2 columns 7 | -ci=2 # Continuation indentation is 2 columns 8 | -vt=0 # Less vertical tightness 9 | -pt=2 # High parenthesis tightness 10 | -bt=2 # High brace tightness 11 | -sbt=2 # High square bracket tightness 12 | -wn # Weld nested containers 13 | -isbc # Don't indent comments without leading space 14 | -cab=0 # Break after comma (comma arrow breakpoints) 15 | -novalign -------------------------------------------------------------------------------- /.replyrc: -------------------------------------------------------------------------------- 1 | [Editor] 2 | [Interrupt] 3 | [FancyPrompt] 4 | [DataDumper] 5 | [AutoRefresh] 6 | 7 | [Colors] 8 | [Hints] 9 | [LexicalPersistence] 10 | [LoadClass] 11 | [Nopaste] 12 | [Packages] 13 | [Pager] 14 | [ReadLine] 15 | [ResultCache] 16 | 17 | [Autocomplete::Commands] 18 | [Autocomplete::Functions] 19 | [Autocomplete::Globals] 20 | [Autocomplete::Keywords] 21 | [Autocomplete::Lexicals] 22 | [Autocomplete::Methods] 23 | [Autocomplete::Packages] -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Pledge 2 | 3 | In the interest of fostering an open, inclusive, and welcoming environment, we, 4 | as contributors and maintainers pledge, to the best of our ability, to make 5 | participation in our project and our community an enjoyable experience for 6 | everyone involved. 7 | 8 | ## Standards 9 | 10 | Examples of acceptable behavior by participants include: 11 | 12 | * Being polite and respectful in communication 13 | * Willing to give and receive constructive criticism 14 | * Advancing the successful development of the project 15 | * Being a productive member of the community 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * Being impolite or disrespectful in communication 20 | * Unwilling to receive constructive criticism 21 | * Hindering the successful development of the project 22 | * Being an unproductive member of the community 23 | 24 | ## Maintainership 25 | 26 | Project maintainers are responsible for clarifying the standards of acceptable 27 | behavior and are expected to take appropriate and fair corrective action in 28 | response to any instances of unacceptable behavior. Project maintainers have 29 | the right and responsibility to remove, edit, or reject comments, commits, 30 | code, wiki edits, issues, and other contributions that are not aligned with 31 | this Code of Conduct, or to ban temporarily or permanently any contributor for 32 | other behaviors that they deem inappropriate. 33 | 34 | Additionally, project maintainers are obligated to: 35 | 36 | * Help contributors 37 | * Review comments, commits, issues, and other project contributions 38 | * Approve comments, commits, issues, and other project contributions 39 | * Enforce community guidelines 40 | 41 | ### Policy Scope 42 | 43 | This Code of Conduct applies only and exclusively to official project spaces, 44 | mediums, and accounts owned by and representative of the project. Examples of 45 | project representation include using an official project e-mail address, 46 | posting via an official social media account or acting as an appointed 47 | representative at an online or offline event. 48 | 49 | Please take note that this does not include the personal public or private 50 | social media accounts, non-project related websites, emails, communications or 51 | activities online or offline, of any participant of this project, maintainer 52 | and individual contributor alike. Representation of the project may be further 53 | defined and clarified by project maintainers. 54 | 55 | ### Policy Enforcement 56 | 57 | Instances of violations may be reported by contacting the project maintainers. 58 | All complaints will be reviewed and investigated and will result in a response 59 | that is deemed necessary and appropriate to the circumstances. The project team 60 | is obligated to maintain confidentiality with regard to the reporter of an 61 | incident. Further details of specific enforcement policies may be posted 62 | separately. -------------------------------------------------------------------------------- /MANIFEST.SKIP: -------------------------------------------------------------------------------- 1 | ^(?!CHANGES$|INSTALL|LICENSE|Makefile.PL|MANIFEST|META*|README$|cpanfile$|examples\/.*|bin\/vns$|lib\/.*|t\/.*).*$ -------------------------------------------------------------------------------- /META.json: -------------------------------------------------------------------------------- 1 | { 2 | "abstract" : "OO Library for Perl 5", 3 | "author" : [ 4 | "AWNCORP " 5 | ], 6 | "dynamic_config" : 0, 7 | "generated_by" : "Dist::Zilla version 6.030, CPAN::Meta::Converter version 2.150010", 8 | "license" : [ 9 | "apache_2_0" 10 | ], 11 | "meta-spec" : { 12 | "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", 13 | "version" : 2 14 | }, 15 | "name" : "Venus", 16 | "prereqs" : { 17 | "configure" : { 18 | "requires" : { 19 | "ExtUtils::MakeMaker" : "0" 20 | } 21 | }, 22 | "runtime" : { 23 | "requires" : { 24 | "perl" : "5.018" 25 | } 26 | }, 27 | "test" : { 28 | "requires" : { 29 | "perl" : "5.018" 30 | } 31 | } 32 | }, 33 | "release_status" : "stable", 34 | "resources" : { 35 | "bugtracker" : { 36 | "web" : "http://github.com/awncorp/venus/issues" 37 | }, 38 | "homepage" : "https://metacpan.org/dist/Venus", 39 | "license" : [ 40 | "https://opensource.org/licenses/apache-2.0" 41 | ], 42 | "repository" : { 43 | "type" : "git", 44 | "url" : "git://github.com/awncorp/venus.git", 45 | "web" : "http://github.com/awncorp/venus" 46 | } 47 | }, 48 | "version" : "4.11", 49 | "x_authority" : "cpan:AWNCORP", 50 | "x_generated_by_perl" : "v5.34.0", 51 | "x_serialization_backend" : "Cpanel::JSON::XS version 4.30", 52 | "x_spdx_expression" : "Apache-2.0" 53 | } 54 | 55 | -------------------------------------------------------------------------------- /META.yml: -------------------------------------------------------------------------------- 1 | --- 2 | abstract: 'OO Library for Perl 5' 3 | author: 4 | - 'AWNCORP ' 5 | build_requires: 6 | perl: '5.018' 7 | configure_requires: 8 | ExtUtils::MakeMaker: '0' 9 | dynamic_config: 0 10 | generated_by: 'Dist::Zilla version 6.030, CPAN::Meta::Converter version 2.150010' 11 | license: apache 12 | meta-spec: 13 | url: http://module-build.sourceforge.net/META-spec-v1.4.html 14 | version: '1.4' 15 | name: Venus 16 | requires: 17 | perl: '5.018' 18 | resources: 19 | bugtracker: http://github.com/awncorp/venus/issues 20 | homepage: https://metacpan.org/dist/Venus 21 | license: https://opensource.org/licenses/apache-2.0 22 | repository: git://github.com/awncorp/venus.git 23 | version: '4.11' 24 | x_authority: cpan:AWNCORP 25 | x_generated_by_perl: v5.34.0 26 | x_serialization_backend: 'YAML::Tiny version 1.74' 27 | x_spdx_expression: Apache-2.0 28 | -------------------------------------------------------------------------------- /Makefile.PL: -------------------------------------------------------------------------------- 1 | # This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v6.030. 2 | use strict; 3 | use warnings; 4 | 5 | use 5.018; 6 | 7 | use ExtUtils::MakeMaker; 8 | 9 | my %WriteMakefileArgs = ( 10 | "ABSTRACT" => "OO Library for Perl 5", 11 | "AUTHOR" => "AWNCORP ", 12 | "CONFIGURE_REQUIRES" => { 13 | "ExtUtils::MakeMaker" => 0 14 | }, 15 | "DISTNAME" => "Venus", 16 | "EXE_FILES" => [ 17 | "bin/vns" 18 | ], 19 | "LICENSE" => "apache", 20 | "MIN_PERL_VERSION" => "5.018", 21 | "NAME" => "Venus", 22 | "PREREQ_PM" => {}, 23 | "VERSION" => "4.11", 24 | "test" => { 25 | "TESTS" => "t/*.t" 26 | } 27 | ); 28 | 29 | 30 | my %FallbackPrereqs = (); 31 | 32 | 33 | unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) { 34 | delete $WriteMakefileArgs{TEST_REQUIRES}; 35 | delete $WriteMakefileArgs{BUILD_REQUIRES}; 36 | $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs; 37 | } 38 | 39 | delete $WriteMakefileArgs{CONFIGURE_REQUIRES} 40 | unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; 41 | 42 | WriteMakefile(%WriteMakefileArgs); 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Venus - Object-Oriented Standard Library for Perl 5 2 | 3 | Venus is an object-orientation framework and extendible standard library for 4 | Perl 5 with classes which wrap most native [Perl](https://www.perl.org/) data 5 | types. Venus has a simple modular architecture, robust library of classes and 6 | methods, supports pure-Perl autoboxing, advanced exception handling, "true" and 7 | "false" keywords, package introspection, command-line options parsing, and 8 | more. 9 | 10 | ## Installation 11 | 12 | Install Venus using [cpm](https://metacpan.org/pod/App::cpm): 13 | 14 | ```bash 15 | cpm install Venus 16 | ``` 17 | 18 | Install Venus using [cpanm](https://metacpan.org/pod/App::cpanminus): 19 | 20 | ```bash 21 | cpanm -qn Venus 22 | ``` 23 | 24 | Install Venus using Perl (via cpanm): 25 | 26 | ```bash 27 | curl -sSL https://cpanmin.us | perl - -qn Venus 28 | ``` 29 | 30 | Install Venus using Perl (via cpanm, from GitHub): 31 | 32 | ```bash 33 | curl -ssL https://cpanmin.us | perl - -qn https://github.com/awncorp/venus.zip 34 | ``` 35 | 36 | ## Features 37 | 38 | - Perl 5.18.0+ 39 | - Zero Dependencies 40 | - Fast Object-Orientation 41 | - Robust Standard Library 42 | - Intuitive Value Classes 43 | - Pure Perl Autoboxing 44 | - Convenient Utility Classes 45 | - Simple Package Reflection 46 | - Flexible Exception Handling 47 | - Composable Standards 48 | - Pluggable (no monkeypatching) 49 | - Proxyable Methods 50 | - Type Assertions 51 | - Type Coercions 52 | - Value Casting 53 | - Boolean Values 54 | - Complete Documentation 55 | - Complete Test Coverage 56 | 57 | ## Founder 58 | 59 | - [@awncorp](https://github.com/awncorp) 60 | 61 | ## Contributing 62 | 63 | We rely on your contributions and feedback to improve Venus, and we love 64 | hearing about your experiences and what we can improve upon. 65 | 66 | All contributions are always welcome! See the [contributing 67 | guide](https://github.com/awncorp/venus/blob/master/CONTRIBUTING.md) for ways 68 | to get started, and please adhere to this project's [code of 69 | conduct](https://github.com/awncorp/venus/blob/master/CODE_OF_CONDUCT.md). 70 | 71 | ## Support 72 | 73 | For support, feel free to report an [issue](https://github.com/awncorp/venus/issues). 74 | 75 | ## License 76 | 77 | [Apache 2](https://choosealicense.com/licenses/apache-2.0/) 78 | -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | # Release 2 | 3 | ## Version: 4.11 4 | 5 | - [feature] Implement Venus::Assert#includes 6 | - [feature] Implement Venus::Future 7 | - [feature] Refactor Venus::Assert, Implement Venus::{Coercion,Constraint} 8 | - [feature] Implement Venus::Space#{patch,patched,unpatch} 9 | - [feature] Implement Venus::Sealed 10 | - [feature] Implement Venus::Atom 11 | - [feature] Implement Venus::Enum 12 | - [feature] Implement Venus::Role::Superable 13 | - [feature] Implement Venus::Role::Patchable 14 | - [feature] Implement Venus#clone 15 | - [feature] Implement Venus::Process#future 16 | - [feature] Implement Venus::Future#wait 17 | - [update] Refactor Venus::Test 18 | - [update] Add test and documentation for Venus::Process#is_dyadic 19 | - [update] Update Venus::Process#await, auto-reap processes 20 | - [update] Research CPANTS issue with Venus::Process 21 | - [update] Update Venus::Process, prevent PPID in dyads 22 | - [update] Use Venus::Check types in all signatures 23 | - [update] Update Venus#async to return Venus::Future 24 | 25 | 26 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 4.11 2 | -------------------------------------------------------------------------------- /bin/vns: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | package main; 4 | 5 | use 5.018; 6 | 7 | use strict; 8 | use warnings; 9 | 10 | BEGIN { 11 | $ENV{VENUS_TASK_AUTO} = 1; 12 | $ENV{VENUS_TASK_NAME} = 'vns'; 13 | } 14 | 15 | use Venus::Run; 16 | 17 | 1; 18 | 19 | =encoding utf8 20 | 21 | =head1 NAME 22 | 23 | vns 24 | 25 | =head1 SYNOPSIS 26 | 27 | vns init 28 | 29 | =head1 DESCRIPTION 30 | 31 | Run and alias arbitrary commands, and tasks derived from L, using 32 | L. See L for usage and configuration 33 | information. 34 | 35 | =head1 QUICKSTART 36 | 37 | # Mint a new configuration file 38 | vns init 39 | 40 | # Install a distribution 41 | vns cpan $DIST 42 | 43 | # Install dependencies in the CWD 44 | vns deps 45 | 46 | # Check that a package can be compiled 47 | vns okay $FILE 48 | 49 | # Use the Perl debugger as a REPL 50 | vns repl 51 | 52 | # Evaluate arbitrary Perl expressions 53 | vns exec "say 'hello'" 54 | 55 | # Test the Perl project in the CWD 56 | vns test t 57 | 58 | =head1 SEE ALSO 59 | 60 | L, L, L. 61 | 62 | =cut 63 | -------------------------------------------------------------------------------- /cpanfile: -------------------------------------------------------------------------------- 1 | # This file is generated by Dist::Zilla::Plugin::CPANFile v6.030 2 | # Do not edit this file directly. To change prereqs, edit the `dist.ini` file. 3 | 4 | requires "perl" => "5.018"; 5 | 6 | on 'test' => sub { 7 | requires "perl" => "5.018"; 8 | }; 9 | 10 | on 'configure' => sub { 11 | requires "ExtUtils::MakeMaker" => "0"; 12 | }; 13 | -------------------------------------------------------------------------------- /dist.ini: -------------------------------------------------------------------------------- 1 | name = Venus 2 | abstract = OO Library for Perl 5 3 | main_module = lib/Venus.pm 4 | author = AWNCORP 5 | license = Apache_2_0 6 | copyright_holder = Al Newkirk 7 | copyright_year = 2022 8 | 9 | [Authority] 10 | authority = cpan:AWNCORP 11 | do_munging = 0 12 | 13 | [@Filter] 14 | -bundle = @Basic 15 | -remove = GatherDir 16 | -remove = Readme 17 | -remove = UploadToCPAN 18 | 19 | [ExecDir] 20 | [MetaJSON] 21 | [ManifestSkip] 22 | [FakeRelease] 23 | [CoalescePod] 24 | 25 | [ReadmeAnyFromPod / ReadmeTextInBuild] 26 | source_filename = lib/Venus.pm 27 | filename = README 28 | 29 | [CopyFilesFromBuild] 30 | copy = LICENSE 31 | copy = META.json 32 | copy = META.yml 33 | copy = Makefile.PL 34 | copy = README 35 | copy = cpanfile 36 | 37 | [@Git] 38 | tag_format = %v 39 | tag_message = Release: %v 40 | changelog = CHANGES 41 | 42 | [Git::GatherDir] 43 | include_dotfiles = 1 44 | exclude_filename = LICENSE 45 | exclude_filename = META.json 46 | exclude_filename = META.yml 47 | exclude_filename = Makefile.PL 48 | exclude_filename = README 49 | exclude_filename = cpanfile 50 | 51 | [Git::NextVersion] 52 | first_version = 0.01 53 | version_regexp = ^(.+)$ 54 | 55 | [Git::CommitBuild] 56 | branch = builds 57 | message = Build %h (on %b) 58 | multiple_inheritance = 0 59 | 60 | [MetaResources] 61 | homepage = https://metacpan.org/dist/Venus 62 | license = https://opensource.org/licenses/apache-2.0 63 | bugtracker.web = http://github.com/awncorp/venus/issues 64 | repository.url = git://github.com/awncorp/venus.git 65 | repository.web = http://github.com/awncorp/venus 66 | repository.type = git 67 | 68 | [Run::BeforeRelease] 69 | run = git add . 70 | run = git commit -m "Built release version %v" 71 | 72 | [Prereqs] 73 | perl = 5.018 74 | 75 | [Prereqs / TestRequires] 76 | perl = 5.018 77 | 78 | [InstallGuide] 79 | [CPANFile] 80 | -------------------------------------------------------------------------------- /examples/box.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::String; 9 | 10 | # 11 | # Opt-in to autoboxing 12 | # 13 | 14 | Venus::String->new('hello world')->box->do('say')->lowercase->titlecase->do('say')->say('get'); 15 | -------------------------------------------------------------------------------- /examples/cli.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Cli; 9 | 10 | # 11 | # Easily create CLIs 12 | # 13 | 14 | Venus::Cli->new->set('opt', 'help', { help => 'Show help' })->say_string('help'); 15 | -------------------------------------------------------------------------------- /examples/count.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Path; 9 | use Venus::Space; 10 | 11 | # 12 | # Count the lines in the files of packages 13 | # 14 | 15 | Venus::Path->new(Venus::Space->new($_)->do('say', 'package')->locate)->box->lines->say('count') for qw( 16 | Venus::Array 17 | Venus::Hash 18 | Venus::Number 19 | Venus::String 20 | ); 21 | -------------------------------------------------------------------------------- /examples/data.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Data; 9 | 10 | # 11 | # Access content in the DATA token 12 | # 13 | 14 | Venus::Data->new($0)->text->say('search', {list => undef, name => 'greet'}); 15 | 16 | __DATA__ 17 | 18 | @@ greet 19 | 20 | Hello World. 21 | 22 | @@ cut 23 | -------------------------------------------------------------------------------- /examples/date.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Date; 9 | 10 | # 11 | # ISO8601 string, 2 days from the start of the month 12 | # 13 | 14 | Venus::Date->new->restart_month->add_days(2)->say('iso8601'); 15 | -------------------------------------------------------------------------------- /examples/deduce.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Type; 9 | 10 | # 11 | # Deduce and reify hierarchical values 12 | # 13 | 14 | Venus::Type->new({name => ['Ready', 'Robot'], version => 0.12, stable => !!1,})->say_pretty('deduce_deep'); 15 | -------------------------------------------------------------------------------- /examples/dump.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Dump; 9 | 10 | # 11 | # Dump Perl data structure as string 12 | # 13 | 14 | Venus::Dump->new({name => ['Ready', 'Robot'], version => 0.12, stable => !!1})->say_string('encode'); 15 | -------------------------------------------------------------------------------- /examples/equality.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Number; 9 | 10 | # 11 | # perform smart-match equality 12 | # 13 | 14 | Venus::Number->new(0)->say('is_true', @$_) for ( 15 | # e.g. 0 ~~ '' 16 | ['eq', ''], 17 | # e.g. 0 eq '' 18 | ['tv', ''], 19 | # e.g. 0 ~~ bless{} 20 | ['eq', bless{}], 21 | # e.g. 0 ~~ Venus::Number->new 22 | ['eq', Venus::Number->new], 23 | # e.g. 0 eq Venus::Number->new 24 | ['tv', Venus::Number->new], 25 | # e.g. 0 eq Venus::Number->new(0) 26 | ['tv', Venus::Number->new(0)], 27 | # e.g. 0 eq Venus::Number->new(1) 28 | ['tv', Venus::Number->new(1)], 29 | ); 30 | -------------------------------------------------------------------------------- /examples/error.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Path; 9 | 10 | # 11 | # Catch file open error 12 | # 13 | 14 | Venus::Path->new('/path/to/nowhere')->catch('open')->say('message'); 15 | 16 | # 17 | # Catch path error throw 18 | # 19 | 20 | Venus::Path->new('/path/to/nowhere')->throw->catch('error', {message => 'Missing file'})->say('message'); 21 | -------------------------------------------------------------------------------- /examples/gather.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Gather; 9 | 10 | # 11 | # Gather and transform inputs 12 | # 13 | 14 | Venus::Gather->new 15 | ->when(sub{$_ eq 1})->then(sub{"one"}) 16 | ->when(sub{$_ eq 2})->then(sub{"two"}) 17 | ->none(sub{"?"}) 18 | ->say('result', [@ARGV]); 19 | -------------------------------------------------------------------------------- /examples/ipc.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Process; 9 | 10 | # 11 | # Launch 5 processes, pool, and communicate 12 | # 13 | 14 | my $parent = Venus::Process->new; 15 | 16 | $parent->works(5, sub { 17 | my ($process) = @_; 18 | $process->join('team')->pool(5, 5)->send($process->ppid, { 19 | from => $process->pid, said => "hello", 20 | }); 21 | }); 22 | 23 | $parent->join('team')->sync(5, 5)->say_json('recvall'); 24 | -------------------------------------------------------------------------------- /examples/json.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Json; 9 | 10 | # 11 | # Use available JSON lib for encoding 12 | # 13 | 14 | Venus::Json->new({name => ['Ready', 'Robot'], version => 0.12, stable => !!1})->say_string('encode'); 15 | -------------------------------------------------------------------------------- /examples/mappable.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Hash; 9 | use Venus::Array; 10 | 11 | # 12 | # Map over items, and uppercase each 13 | # 14 | 15 | Venus::Array->new(['a'..'d'])->say('call', 'map', 'uppercase'); 16 | 17 | # 18 | # Map over items, and uppercase each 19 | # 20 | 21 | Venus::Hash->new({a=>'a',b=>'b',c=>'c',d=>'d'})->say('call', 'map', 'uppercase'); 22 | -------------------------------------------------------------------------------- /examples/match.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Match; 9 | 10 | # 11 | # Match and return expressions 12 | # 13 | 14 | Venus::Match->new 15 | ->when(sub{defined && $_ < 5})->then(sub{"< 5"}) 16 | ->when(sub{defined && $_ > 5})->then(sub{"> 5"}) 17 | ->none(sub{"?"}) 18 | ->say('result', @ARGV); 19 | -------------------------------------------------------------------------------- /examples/ones.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus; 9 | use Venus::Type; 10 | 11 | # 12 | # Deduce number, string, scalarref, boolean, boolean 13 | # 14 | 15 | Venus::Type->new($_)->deduce->say for 1, "1", \1, !!1, true; 16 | -------------------------------------------------------------------------------- /examples/os.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Os; 9 | 10 | # 11 | # Identify and report the current OS 12 | # 13 | 14 | Venus::Os->new->say('type'); 15 | -------------------------------------------------------------------------------- /examples/path.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Path; 9 | 10 | # 11 | # Print the CWD 12 | # 13 | 14 | Venus::Path->new->say_string('absolute'); 15 | -------------------------------------------------------------------------------- /examples/processes.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Process; 9 | 10 | # 11 | # Launch 5 processes and report all PIDs 12 | # 13 | 14 | Venus::Process->new->do('works', 5, sub {warn $_})->do('waitall')->say('get'); 15 | -------------------------------------------------------------------------------- /examples/random.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Random; 9 | 10 | # 11 | # Generate 100 random characters 12 | # 13 | 14 | Venus::Random->new->say('collect', 100, 'character'); 15 | -------------------------------------------------------------------------------- /examples/yaml.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Yaml; 9 | 10 | # 11 | # Use available YAML lib for encoding 12 | # 13 | 14 | Venus::Yaml->new({name => ['Ready', 'Robot'], version => 0.12, stable => !!1})->say_string('encode'); 15 | -------------------------------------------------------------------------------- /examples/zeros.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus; 9 | use Venus::Type; 10 | 11 | # 12 | # Deduce number, string, scalarref, boolean, boolean 13 | # 14 | 15 | Venus::Type->new($_)->deduce->say for 0, "0", \0, !!0, false; 16 | -------------------------------------------------------------------------------- /lib/Venus/Args.pm: -------------------------------------------------------------------------------- 1 | package Venus::Args; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Class 'attr', 'base', 'with'; 9 | 10 | base 'Venus::Kind::Utility'; 11 | 12 | with 'Venus::Role::Valuable'; 13 | with 'Venus::Role::Buildable'; 14 | with 'Venus::Role::Accessible'; 15 | with 'Venus::Role::Proxyable'; 16 | 17 | # ATTRIBUTES 18 | 19 | attr 'named'; 20 | 21 | # BUILDERS 22 | 23 | sub build_proxy { 24 | my ($self, $package, $method, $value) = @_; 25 | 26 | my $has_value = exists $_[3]; 27 | 28 | return sub { 29 | return $self->get($method) if !$has_value; # no value 30 | return $self->set($method, $value); 31 | }; 32 | } 33 | 34 | sub build_self { 35 | my ($self, $data) = @_; 36 | 37 | $self->named({}) if !$self->named; 38 | 39 | return $self; 40 | } 41 | 42 | # METHODS 43 | 44 | sub assertion { 45 | my ($self) = @_; 46 | 47 | my $assertion = $self->SUPER::assertion; 48 | 49 | $assertion->match('arrayref')->format(sub{ 50 | (ref $self || $self)->new($_) 51 | }); 52 | 53 | return $assertion; 54 | } 55 | 56 | sub default { 57 | my ($self) = @_; 58 | 59 | return [@ARGV]; 60 | } 61 | 62 | sub exists { 63 | my ($self, $name) = @_; 64 | 65 | return if not defined $name; 66 | 67 | my $pos = $self->name($name); 68 | 69 | return if not defined $pos; 70 | 71 | return CORE::exists $self->indexed->{$pos}; 72 | } 73 | 74 | sub get { 75 | my ($self, $name) = @_; 76 | 77 | return if not defined $name; 78 | 79 | my $pos = $self->name($name); 80 | 81 | return if not defined $pos; 82 | 83 | return $self->indexed->{$pos}; 84 | } 85 | 86 | sub indexed { 87 | my ($self) = @_; 88 | 89 | return {map +($_, $self->value->[$_]), 0..$#{$self->value}}; 90 | } 91 | 92 | sub name { 93 | my ($self, $name) = @_; 94 | 95 | if (defined $self->named->{$name}) { 96 | return $self->named->{$name}; 97 | } 98 | 99 | if (defined $self->indexed->{$name}) { 100 | return $name; 101 | } 102 | 103 | return undef; 104 | } 105 | 106 | sub set { 107 | my ($self, $name, $data) = @_; 108 | 109 | return if not defined $name; 110 | 111 | my $pos = $self->name($name); 112 | 113 | return if not defined $pos; 114 | 115 | return $self->value->[$pos] = $data; 116 | } 117 | 118 | sub unnamed { 119 | my ($self) = @_; 120 | 121 | my $list = []; 122 | 123 | my $argv = $self->indexed; 124 | my $data = +{reverse %{$self->named}}; 125 | 126 | for my $index (sort keys %$argv) { 127 | unless (exists $data->{$index}) { 128 | push @$list, $argv->{$index}; 129 | } 130 | } 131 | 132 | return $list; 133 | } 134 | 135 | 1; 136 | -------------------------------------------------------------------------------- /lib/Venus/Atom.pm: -------------------------------------------------------------------------------- 1 | package Venus::Atom; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Class 'base'; 9 | 10 | base 'Venus::Sealed'; 11 | 12 | use overload ( 13 | '""' => sub{$_[0]->get // ''}, 14 | '~~' => sub{$_[0]->get // ''}, 15 | 'eq' => sub{($_[0]->get // '') eq "$_[1]"}, 16 | 'ne' => sub{($_[0]->get // '') ne "$_[1]"}, 17 | 'qr' => sub{qr/@{[quotemeta($_[0])]}/}, 18 | fallback => 1, 19 | ); 20 | 21 | # METHODS 22 | 23 | sub __get { 24 | my ($self, $init, $data) = @_; 25 | 26 | return $init->{value}; 27 | } 28 | 29 | sub __set { 30 | my ($self, $init, $data, $value) = @_; 31 | 32 | if (ref $value || !defined $value || $value eq '') { 33 | return undef; 34 | } 35 | 36 | return $init->{value} = $value if !exists $init->{value}; 37 | 38 | return $self->error({throw => 'error_on_set', value => $value}); 39 | } 40 | 41 | # ERRORS 42 | 43 | sub error_on_set { 44 | my ($self, $data) = @_; 45 | 46 | my $message = 'Can\'t re-set atom value to "{{value}}"'; 47 | 48 | my $stash = { 49 | value => $data->{value}, 50 | }; 51 | 52 | my $result = { 53 | name => 'on.set', 54 | raise => true, 55 | stash => $stash, 56 | message => $message, 57 | }; 58 | 59 | return $result; 60 | } 61 | 62 | 1; 63 | -------------------------------------------------------------------------------- /lib/Venus/Box.pm: -------------------------------------------------------------------------------- 1 | package Venus::Box; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Class 'with'; 9 | 10 | with 'Venus::Role::Buildable'; 11 | with 'Venus::Role::Proxyable'; 12 | 13 | # BUILDERS 14 | 15 | sub build_arg { 16 | my ($self, $data) = @_; 17 | 18 | return { 19 | value => $data, 20 | }; 21 | } 22 | 23 | sub build_args { 24 | my ($self, $data) = @_; 25 | 26 | if (keys %$data == 1 && exists $data->{value}) { 27 | return $data; 28 | } 29 | return { 30 | value => $data, 31 | }; 32 | } 33 | 34 | sub build_self { 35 | my ($self, $data) = @_; 36 | 37 | require Venus::Type; 38 | 39 | $data //= {}; 40 | 41 | $self->{value} = Venus::Type->new(value => $data->{value})->deduce; 42 | 43 | return $self; 44 | } 45 | 46 | sub build_proxy { 47 | my ($self, $package, $method, @args) = @_; 48 | 49 | require Scalar::Util; 50 | 51 | my $value = $self->{value}; 52 | 53 | if (not(Scalar::Util::blessed($value))) { 54 | require Venus::Error; 55 | return Venus::Error->throw( 56 | "$package can only operate on objects, not $value" 57 | ); 58 | } 59 | if (!$value->can($method)) { 60 | if (my $handler = $self->can("__handle__${method}")) { 61 | return sub {$self->$handler(@args)}; 62 | } 63 | elsif (!$value->can('AUTOLOAD')) { 64 | return undef; 65 | } 66 | } 67 | return sub { 68 | local $_ = $value; 69 | my $result = [ 70 | $value->$method(@args) 71 | ]; 72 | $result = $result->[0] if @$result == 1; 73 | if (Scalar::Util::blessed($result)) { 74 | return not(UNIVERSAL::isa($result, 'Venus::Box')) 75 | ? ref($self)->new(value => $result) 76 | : $result; 77 | } 78 | else { 79 | require Venus::Type; 80 | return ref($self)->new( 81 | value => Venus::Type->new(value => $result)->deduce 82 | ); 83 | } 84 | }; 85 | } 86 | 87 | # METHODS 88 | 89 | sub __handle__unbox { 90 | my ($self, $code, @args) = @_; 91 | return $code ? $self->$code(@args)->{value} : $self->{value}; 92 | } 93 | 94 | 1; 95 | -------------------------------------------------------------------------------- /lib/Venus/Box.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Box - Box Class 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Box Class for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package main; 17 | 18 | use Venus::Box; 19 | 20 | my $box = Venus::Box->new( 21 | value => {}, 22 | ); 23 | 24 | # $box->keys->count->unbox; 25 | 26 | =cut 27 | 28 | =head1 DESCRIPTION 29 | 30 | This package provides a pure Perl boxing mechanism for wrapping objects and 31 | values, and chaining method calls across all objects. 32 | 33 | =cut 34 | 35 | =head1 INTEGRATES 36 | 37 | This package integrates behaviors from: 38 | 39 | L 40 | 41 | L 42 | 43 | =cut 44 | 45 | =head1 METHODS 46 | 47 | This package provides the following methods: 48 | 49 | =cut 50 | 51 | =head2 unbox 52 | 53 | unbox(string $method, any @args) (any) 54 | 55 | The unbox method returns the un-boxed underlying object. This is a virtual 56 | method that dispatches to C<__handle__unbox>. This method supports dispatching, 57 | i.e. providing a method name and arguments whose return value will be acted on 58 | by this method. 59 | 60 | I> 61 | 62 | =over 4 63 | 64 | =item unbox example 1 65 | 66 | # given: synopsis; 67 | 68 | my $unbox = $box->unbox; 69 | 70 | # bless({ value => {} }, "Venus::Hash") 71 | 72 | =back 73 | 74 | =over 4 75 | 76 | =item unbox example 2 77 | 78 | # given: synopsis; 79 | 80 | my $unbox = $box->unbox('count'); 81 | 82 | # 0 83 | 84 | =back 85 | 86 | =cut 87 | 88 | =head1 AUTHORS 89 | 90 | Awncorp, C 91 | 92 | =cut 93 | 94 | =head1 LICENSE 95 | 96 | Copyright (C) 2000, Awncorp, C. 97 | 98 | This program is free software, you can redistribute it and/or modify it under 99 | the terms of the Apache license version 2.0. 100 | 101 | =cut -------------------------------------------------------------------------------- /lib/Venus/Code.pm: -------------------------------------------------------------------------------- 1 | package Venus::Code; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Class 'base'; 9 | 10 | base 'Venus::Kind::Value'; 11 | 12 | use overload ( 13 | '&{}' => sub{$_[0]->value}, 14 | fallback => 1, 15 | ); 16 | 17 | # METHODS 18 | 19 | sub assertion { 20 | my ($self) = @_; 21 | 22 | my $assert = $self->SUPER::assertion; 23 | 24 | $assert->clear->expression('coderef'); 25 | 26 | return $assert; 27 | } 28 | 29 | sub call { 30 | my ($self, @args) = @_; 31 | 32 | my $data = $self->get; 33 | 34 | return $data->(@args); 35 | } 36 | 37 | sub compose { 38 | my ($self, $code, @args) = @_; 39 | 40 | my $data = $self->get; 41 | 42 | return sub { (sub { $code->($data->(@_)) })->(@args, @_) }; 43 | } 44 | 45 | sub conjoin { 46 | my ($self, $code) = @_; 47 | 48 | my $data = $self->get; 49 | 50 | return sub { $data->(@_) && $code->(@_) }; 51 | } 52 | 53 | sub curry { 54 | my ($self, @args) = @_; 55 | 56 | my $data = $self->get; 57 | 58 | return sub { $data->(@args, @_) }; 59 | } 60 | 61 | sub default { 62 | return sub{}; 63 | } 64 | 65 | sub disjoin { 66 | my ($self, $code) = @_; 67 | 68 | my $data = $self->get; 69 | 70 | return sub { $data->(@_) || $code->(@_) }; 71 | } 72 | 73 | sub next { 74 | my ($self, @args) = @_; 75 | 76 | my $data = $self->get; 77 | 78 | return $data->(@args); 79 | } 80 | 81 | sub rcurry { 82 | my ($self, @args) = @_; 83 | 84 | my $data = $self->get; 85 | 86 | return sub { $data->(@_, @args) }; 87 | } 88 | 89 | 1; 90 | -------------------------------------------------------------------------------- /lib/Venus/Coercion.pm: -------------------------------------------------------------------------------- 1 | package Venus::Coercion; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Class 'attr', 'base', 'with'; 9 | 10 | use Venus::Check; 11 | 12 | base 'Venus::Kind::Utility'; 13 | 14 | with 'Venus::Role::Buildable'; 15 | 16 | # ATTRIBUTES 17 | 18 | attr 'on_eval'; 19 | 20 | # BUILDERS 21 | 22 | sub build_arg { 23 | my ($self, $data) = @_; 24 | 25 | return { 26 | on_eval => ref $data eq 'ARRAY' ? $data : [$data], 27 | }; 28 | } 29 | 30 | sub build_args { 31 | my ($self, $data) = @_; 32 | 33 | $data->{on_eval} = [] if !$data->{on_eval}; 34 | 35 | return $data; 36 | } 37 | 38 | # METHODS 39 | 40 | sub accept { 41 | my ($self, $name, @args) = @_; 42 | 43 | if (!$name) { 44 | return $self; 45 | } 46 | if ($self->check->can($name)) { 47 | $self->check->accept($name, @args); 48 | } 49 | else { 50 | $self->check->identity($name, @args); 51 | } 52 | return $self; 53 | } 54 | 55 | sub check { 56 | my ($self, @args) = @_; 57 | 58 | $self->{check} = $args[0] if @args; 59 | 60 | return $self->{check} ||= Venus::Check->new; 61 | } 62 | 63 | sub clear { 64 | my ($self) = @_; 65 | 66 | @{$self->on_eval} = (); 67 | 68 | $self->check->clear; 69 | 70 | return $self; 71 | } 72 | 73 | sub format { 74 | my ($self, @code) = @_; 75 | 76 | push @{$self->on_eval}, @code; 77 | 78 | return $self; 79 | } 80 | 81 | sub eval { 82 | my ($self, $data) = @_; 83 | 84 | if (!$self->check->eval($data)) { 85 | return $data; 86 | } 87 | 88 | for my $callback (@{$self->on_eval}) { 89 | local $_ = $data; 90 | $data = $self->$callback($data); 91 | } 92 | 93 | return $data; 94 | } 95 | 96 | sub evaler { 97 | my ($self) = @_; 98 | 99 | return $self->defer('eval'); 100 | } 101 | 102 | sub result { 103 | my ($self, $data) = @_; 104 | 105 | return $self->eval($data); 106 | } 107 | 108 | 1; 109 | -------------------------------------------------------------------------------- /lib/Venus/Constraint.pm: -------------------------------------------------------------------------------- 1 | package Venus::Constraint; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Class 'attr', 'base', 'with'; 9 | 10 | use Venus::Check; 11 | 12 | base 'Venus::Kind::Utility'; 13 | 14 | with 'Venus::Role::Buildable'; 15 | 16 | # ATTRIBUTES 17 | 18 | attr 'on_eval'; 19 | 20 | # BUILDERS 21 | 22 | sub build_arg { 23 | my ($self, $data) = @_; 24 | 25 | return { 26 | on_eval => ref $data eq 'ARRAY' ? $data : [$data], 27 | }; 28 | } 29 | 30 | sub build_args { 31 | my ($self, $data) = @_; 32 | 33 | $data->{on_eval} = [] if !$data->{on_eval}; 34 | 35 | return $data; 36 | } 37 | 38 | # METHODS 39 | 40 | sub accept { 41 | my ($self, $name, @args) = @_; 42 | 43 | if (!$name) { 44 | return $self; 45 | } 46 | if ($self->check->can($name)) { 47 | $self->check->accept($name, @args); 48 | } 49 | else { 50 | $self->check->identity($name, @args); 51 | } 52 | return $self; 53 | } 54 | 55 | sub check { 56 | my ($self, @args) = @_; 57 | 58 | $self->{check} = $args[0] if @args; 59 | 60 | return $self->{check} ||= Venus::Check->new; 61 | } 62 | 63 | sub clear { 64 | my ($self) = @_; 65 | 66 | @{$self->on_eval} = (); 67 | 68 | $self->check->clear; 69 | 70 | return $self; 71 | } 72 | 73 | sub ensure { 74 | my ($self, @code) = @_; 75 | 76 | push @{$self->on_eval}, @code; 77 | 78 | return $self; 79 | } 80 | 81 | sub eval { 82 | my ($self, $data) = @_; 83 | 84 | my $result = false; 85 | 86 | if (!($result = $self->check->eval($data))) { 87 | return $result; 88 | } 89 | 90 | for my $callback (@{$self->on_eval}) { 91 | local $_ = $data; 92 | $result = $self->$callback($data) ? true : false; 93 | last if !$result; 94 | } 95 | 96 | return $result; 97 | } 98 | 99 | sub evaler { 100 | my ($self) = @_; 101 | 102 | return $self->defer('eval'); 103 | } 104 | 105 | sub result { 106 | my ($self, $data) = @_; 107 | 108 | return $self->eval($data); 109 | } 110 | 111 | 1; 112 | -------------------------------------------------------------------------------- /lib/Venus/Core/Class.pm: -------------------------------------------------------------------------------- 1 | package Venus::Core::Class; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | no warnings 'once'; 9 | 10 | use base 'Venus::Core'; 11 | 12 | # METHODS 13 | 14 | sub BUILD { 15 | my ($self, @data) = @_; 16 | 17 | no strict 'refs'; 18 | 19 | my @roles = @{$self->META->roles}; 20 | 21 | for my $action (grep defined, map *{"${_}::BUILD"}{"CODE"}, @roles) { 22 | $self->$action(@data); 23 | } 24 | 25 | return $self; 26 | } 27 | 28 | sub DESTROY { 29 | my ($self, @data) = @_; 30 | 31 | no strict 'refs'; 32 | 33 | my @mixins = @{$self->META->mixins}; 34 | 35 | for my $action (grep defined, map *{"${_}::DESTROY"}{"CODE"}, @mixins) { 36 | $self->$action(@data); 37 | } 38 | 39 | my @roles = @{$self->META->roles}; 40 | 41 | for my $action (grep defined, map *{"${_}::DESTROY"}{"CODE"}, @roles) { 42 | $self->$action(@data); 43 | } 44 | 45 | return $self; 46 | } 47 | 48 | sub does { 49 | my ($self, @args) = @_; 50 | 51 | return $self->DOES(@args); 52 | } 53 | 54 | sub EXPORT { 55 | my ($self, $into) = @_; 56 | 57 | return []; 58 | } 59 | 60 | sub IMPORT { 61 | my ($self, $into) = @_; 62 | 63 | no strict 'refs'; 64 | no warnings 'redefine'; 65 | 66 | for my $name (@{$self->EXPORT($into)}) { 67 | *{"${into}::${name}"} = \&{"@{[$self->NAME]}::${name}"}; 68 | } 69 | 70 | return $self; 71 | } 72 | 73 | sub import { 74 | my ($self, @args) = @_; 75 | 76 | my $target = caller; 77 | 78 | $self->USE($target); 79 | 80 | return $self->IMPORT($target, @args); 81 | } 82 | 83 | sub meta { 84 | my ($self) = @_; 85 | 86 | return $self->META; 87 | } 88 | 89 | sub new { 90 | my ($self, @args) = @_; 91 | 92 | return $self->BLESS(@args); 93 | } 94 | 95 | sub unimport { 96 | my ($self, @args) = @_; 97 | 98 | my $target = caller; 99 | 100 | return $self->UNIMPORT($target, @args); 101 | } 102 | 103 | 1; 104 | -------------------------------------------------------------------------------- /lib/Venus/Core/Mixin.pm: -------------------------------------------------------------------------------- 1 | package Venus::Core::Mixin; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | no warnings 'once'; 9 | 10 | use base 'Venus::Core'; 11 | 12 | # METHODS 13 | 14 | sub BUILD { 15 | my ($self) = @_; 16 | 17 | return $self; 18 | } 19 | 20 | sub DESTROY { 21 | my ($self) = @_; 22 | 23 | return; 24 | } 25 | 26 | sub EXPORT { 27 | my ($self, $into) = @_; 28 | 29 | return []; 30 | } 31 | 32 | sub IMPORT { 33 | my ($self, $into) = @_; 34 | 35 | no strict 'refs'; 36 | no warnings 'redefine'; 37 | 38 | for my $name (@{$self->EXPORT($into)}) { 39 | *{"${into}::${name}"} = \&{"@{[$self->NAME]}::${name}"}; 40 | } 41 | 42 | return $self; 43 | } 44 | 45 | sub does { 46 | my ($self, @args) = @_; 47 | 48 | return $self->DOES(@args); 49 | } 50 | 51 | sub import { 52 | my ($self) = @_; 53 | 54 | require Venus; 55 | 56 | @_ = ("${self} cannot be used via the \"use\" declaration"); 57 | 58 | goto \&Venus::fault; 59 | } 60 | 61 | sub meta { 62 | my ($self) = @_; 63 | 64 | return $self->META; 65 | } 66 | 67 | sub unimport { 68 | my ($self, @args) = @_; 69 | 70 | my $target = caller; 71 | 72 | return $self->UNIMPORT($target, @args); 73 | } 74 | 75 | 1; 76 | -------------------------------------------------------------------------------- /lib/Venus/Core/Mixin.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Core::Mixin - Mixin Base Class 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Mixin Base Class for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package Person; 17 | 18 | use base 'Venus::Core::Mixin'; 19 | 20 | package User; 21 | 22 | use base 'Venus::Core::Class'; 23 | 24 | package main; 25 | 26 | my $user = User->MIXIN('Person')->new( 27 | fname => 'Elliot', 28 | lname => 'Alderson', 29 | ); 30 | 31 | # bless({fname => 'Elliot', lname => 'Alderson'}, 'User') 32 | 33 | =cut 34 | 35 | =head1 DESCRIPTION 36 | 37 | This package provides a mixin base class with mixin building and object 38 | construction lifecycle hooks. 39 | 40 | =cut 41 | 42 | =head1 INHERITS 43 | 44 | This package inherits behaviors from: 45 | 46 | L 47 | 48 | =cut 49 | 50 | =head1 METHODS 51 | 52 | This package provides the following methods: 53 | 54 | =cut 55 | 56 | =head2 does 57 | 58 | does(string $name) (boolean) 59 | 60 | The does method returns true if the object is composed of the role provided. 61 | 62 | I> 63 | 64 | =over 4 65 | 66 | =item does example 1 67 | 68 | package Employee; 69 | 70 | use base 'Venus::Core::Role'; 71 | 72 | Employee->MIXIN('Person'); 73 | 74 | package main; 75 | 76 | my $user = User->ROLE('Employee')->new( 77 | fname => 'Elliot', 78 | lname => 'Alderson', 79 | ); 80 | 81 | my $does = $user->does('Employee'); 82 | 83 | # 1 84 | 85 | =back 86 | 87 | =cut 88 | 89 | =head2 import 90 | 91 | import(any @args) (any) 92 | 93 | The import method throws a fatal exception whenever the L 94 | declaration is used with mixins as they are meant to be consumed via the 95 | C keyword function. 96 | 97 | I> 98 | 99 | =over 4 100 | 101 | =item import example 1 102 | 103 | package main; 104 | 105 | use Person; 106 | 107 | # Exception! (isa Venus::Fault) 108 | 109 | =back 110 | 111 | =cut 112 | 113 | =head2 meta 114 | 115 | meta() (Venus::Meta) 116 | 117 | The meta method returns a L objects which describes the package's 118 | configuration. 119 | 120 | I> 121 | 122 | =over 4 123 | 124 | =item meta example 1 125 | 126 | package main; 127 | 128 | my $user = User->ROLE('Person')->new( 129 | fname => 'Elliot', 130 | lname => 'Alderson', 131 | ); 132 | 133 | my $meta = Person->meta; 134 | 135 | # bless({...}, 'Venus::Meta') 136 | 137 | =back 138 | 139 | =cut 140 | 141 | =head2 unimport 142 | 143 | unimport(any @args) (any) 144 | 145 | The unimport method invokes the C lifecycle hook and is invoked 146 | whenever the L declaration is used. 147 | 148 | I> 149 | 150 | =over 4 151 | 152 | =item unimport example 1 153 | 154 | package main; 155 | 156 | no Person; 157 | 158 | # () 159 | 160 | =back 161 | 162 | =cut 163 | 164 | =head1 AUTHORS 165 | 166 | Awncorp, C 167 | 168 | =cut 169 | 170 | =head1 LICENSE 171 | 172 | Copyright (C) 2000, Awncorp, C. 173 | 174 | This program is free software, you can redistribute it and/or modify it under 175 | the terms of the Apache license version 2.0. 176 | 177 | =cut -------------------------------------------------------------------------------- /lib/Venus/Core/Role.pm: -------------------------------------------------------------------------------- 1 | package Venus::Core::Role; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | no warnings 'once'; 9 | 10 | use base 'Venus::Core'; 11 | 12 | # METHODS 13 | 14 | sub BUILD { 15 | my ($self, @data) = @_; 16 | 17 | no strict 'refs'; 18 | 19 | my @roles = @{$self->META->roles}; 20 | 21 | for my $action (grep defined, map *{"${_}::BUILD"}{"CODE"}, @roles) { 22 | $self->$action(@data); 23 | } 24 | 25 | return $self; 26 | } 27 | 28 | sub DESTROY { 29 | my ($self, @data) = @_; 30 | 31 | no strict 'refs'; 32 | 33 | my @mixins = @{$self->META->mixins}; 34 | 35 | for my $action (grep defined, map *{"${_}::DESTROY"}{"CODE"}, @mixins) { 36 | $self->$action(@data); 37 | } 38 | 39 | my @roles = @{$self->META->roles}; 40 | 41 | for my $action (grep defined, map *{"${_}::DESTROY"}{"CODE"}, @roles) { 42 | $self->$action(@data); 43 | } 44 | 45 | return $self; 46 | } 47 | 48 | sub EXPORT { 49 | my ($self, $into) = @_; 50 | 51 | return []; 52 | } 53 | 54 | sub IMPORT { 55 | my ($self, $into) = @_; 56 | 57 | no strict 'refs'; 58 | no warnings 'redefine'; 59 | 60 | for my $name (grep !*{"${into}::${_}"}{"CODE"}, @{$self->EXPORT($into)}) { 61 | *{"${into}::${name}"} = \&{"@{[$self->NAME]}::${name}"}; 62 | } 63 | 64 | return $self; 65 | } 66 | 67 | sub does { 68 | my ($self, @args) = @_; 69 | 70 | return $self->DOES(@args); 71 | } 72 | 73 | sub import { 74 | my ($self) = @_; 75 | 76 | require Venus; 77 | 78 | @_ = ("${self} cannot be used via the \"use\" declaration"); 79 | 80 | goto \&Venus::fault; 81 | } 82 | 83 | sub meta { 84 | my ($self) = @_; 85 | 86 | return $self->META; 87 | } 88 | 89 | sub unimport { 90 | my ($self, @args) = @_; 91 | 92 | my $target = caller; 93 | 94 | return $self->UNIMPORT($target, @args); 95 | } 96 | 97 | 1; 98 | -------------------------------------------------------------------------------- /lib/Venus/Dump.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Dump - Dump Class 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Dump Class for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package main; 17 | 18 | use Venus::Dump; 19 | 20 | my $dump = Venus::Dump->new( 21 | value => { name => ['Ready', 'Robot'], version => 0.12, stable => !!1, } 22 | ); 23 | 24 | # $dump->encode; 25 | 26 | =cut 27 | 28 | =head1 DESCRIPTION 29 | 30 | This package provides methods for reading and writing dumped (i.e. 31 | stringified) Perl data. 32 | 33 | =cut 34 | 35 | =head1 ATTRIBUTES 36 | 37 | This package has the following attributes: 38 | 39 | =cut 40 | 41 | =head2 decoder 42 | 43 | decoder(CodeRef) 44 | 45 | This attribute is read-write, accepts C<(CodeRef)> values, and is optional. 46 | 47 | =cut 48 | 49 | =head2 encoder 50 | 51 | encoder(CodeRef) 52 | 53 | This attribute is read-write, accepts C<(CodeRef)> values, and is optional. 54 | 55 | =cut 56 | 57 | =head1 INHERITS 58 | 59 | This package inherits behaviors from: 60 | 61 | L 62 | 63 | =cut 64 | 65 | =head1 INTEGRATES 66 | 67 | This package integrates behaviors from: 68 | 69 | L 70 | 71 | L 72 | 73 | L 74 | 75 | L 76 | 77 | =cut 78 | 79 | =head1 METHODS 80 | 81 | This package provides the following methods: 82 | 83 | =cut 84 | 85 | =head2 decode 86 | 87 | decode(string $text) (any) 88 | 89 | The decode method decodes the Perl string, sets the object value, and returns 90 | the decoded value. 91 | 92 | I> 93 | 94 | =over 4 95 | 96 | =item decode example 1 97 | 98 | # given: synopsis; 99 | 100 | my $decode = $dump->decode('{codename=>["Ready","Robot"],stable=>!!1}'); 101 | 102 | # { codename => ["Ready", "Robot"], stable => 1 } 103 | 104 | =back 105 | 106 | =cut 107 | 108 | =head2 encode 109 | 110 | encode() (string) 111 | 112 | The encode method encodes the objects value as a Perl string and returns the 113 | encoded string. 114 | 115 | I> 116 | 117 | =over 4 118 | 119 | =item encode example 1 120 | 121 | # given: synopsis; 122 | 123 | my $encode = $dump->encode; 124 | 125 | # '{name => ["Ready","Robot"], stable => !!1, version => "0.12"}' 126 | 127 | =back 128 | 129 | =cut 130 | 131 | =head1 AUTHORS 132 | 133 | Awncorp, C 134 | 135 | =cut 136 | 137 | =head1 LICENSE 138 | 139 | Copyright (C) 2000, Awncorp, C. 140 | 141 | This program is free software, you can redistribute it and/or modify it under 142 | the terms of the Apache license version 2.0. 143 | 144 | =cut -------------------------------------------------------------------------------- /lib/Venus/False.pm: -------------------------------------------------------------------------------- 1 | package Venus::False; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Scalar::Util (); 9 | 10 | state $false = Scalar::Util::dualvar(0, "0"); 11 | 12 | use overload ( 13 | '!' => sub{!$false}, 14 | 'bool' => sub{$false}, 15 | fallback => 1, 16 | ); 17 | 18 | # METHODS 19 | 20 | sub new { 21 | return bless({}); 22 | } 23 | 24 | sub value { 25 | return $false; 26 | } 27 | 28 | 1; 29 | -------------------------------------------------------------------------------- /lib/Venus/False.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::False - False Class 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | False Class for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package main; 17 | 18 | use Venus::False; 19 | 20 | my $false = Venus::False->new; 21 | 22 | # $false->value; 23 | 24 | =cut 25 | 26 | =head1 DESCRIPTION 27 | 28 | This package provides the global C value used in L and 29 | the L function. 30 | 31 | =cut 32 | 33 | =head1 METHODS 34 | 35 | This package provides the following methods: 36 | 37 | =cut 38 | 39 | =head2 value 40 | 41 | value() (boolean) 42 | 43 | The value method returns value representing the global C value. 44 | 45 | I> 46 | 47 | =over 4 48 | 49 | =item value example 1 50 | 51 | # given: synopsis; 52 | 53 | my $value = $false->value; 54 | 55 | # 0 56 | 57 | =back 58 | 59 | =cut 60 | 61 | =head1 AUTHORS 62 | 63 | Awncorp, C 64 | 65 | =cut 66 | 67 | =head1 LICENSE 68 | 69 | Copyright (C) 2000, Awncorp, C. 70 | 71 | This program is free software, you can redistribute it and/or modify it under 72 | the terms of the Apache license version 2.0. 73 | 74 | =cut -------------------------------------------------------------------------------- /lib/Venus/Fault.pm: -------------------------------------------------------------------------------- 1 | package Venus::Fault; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use overload ( 9 | '""' => 'explain', 10 | 'eq' => sub{$_[0]->{message} eq "$_[1]"}, 11 | 'ne' => sub{$_[0]->{message} ne "$_[1]"}, 12 | 'qr' => sub{qr/@{[quotemeta($_[0]->{message})]}/}, 13 | '~~' => 'explain', 14 | fallback => 1, 15 | ); 16 | 17 | # METHODS 18 | 19 | sub new { 20 | return bless({message => $_[1] || 'Exception!'})->trace; 21 | } 22 | 23 | sub explain { 24 | my ($self) = @_; 25 | 26 | $self->trace(1) if !@{$self->frames}; 27 | 28 | my $frames = $self->{'$frames'}; 29 | 30 | my $file = $frames->[0][1]; 31 | my $line = $frames->[0][2]; 32 | my $pack = $frames->[0][0]; 33 | my $subr = $frames->[0][3]; 34 | 35 | my $message = $self->{message}; 36 | 37 | my @stacktrace = ("$message in $file at line $line"); 38 | 39 | push @stacktrace, 'Traceback (reverse chronological order):' if @$frames > 1; 40 | 41 | @stacktrace = (join("\n\n", grep defined, @stacktrace), ''); 42 | 43 | for (my $i = 1; $i < @$frames; $i++) { 44 | my $pack = $frames->[$i][0]; 45 | my $file = $frames->[$i][1]; 46 | my $line = $frames->[$i][2]; 47 | my $subr = $frames->[$i][3]; 48 | 49 | push @stacktrace, "$subr\n in $file at line $line"; 50 | } 51 | 52 | return join "\n", @stacktrace, ""; 53 | } 54 | 55 | sub frames { 56 | my ($self) = @_; 57 | 58 | return $self->{'$frames'} //= []; 59 | } 60 | 61 | sub throw { 62 | my ($self, @args) = @_; 63 | 64 | $self = $self->new(@args) if !ref $self; 65 | 66 | die $self; 67 | } 68 | 69 | sub trace { 70 | my ($self, $offset, $limit) = @_; 71 | 72 | my $frames = $self->frames; 73 | 74 | @$frames = (); 75 | 76 | for (my $i = $offset // 1; my @caller = caller($i); $i++) { 77 | push @$frames, [@caller]; 78 | 79 | last if defined $limit && $i + 1 == $offset + $limit; 80 | } 81 | 82 | return $self; 83 | } 84 | 85 | 1; 86 | -------------------------------------------------------------------------------- /lib/Venus/Float.pm: -------------------------------------------------------------------------------- 1 | package Venus::Float; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Class 'base'; 9 | 10 | base 'Venus::Number'; 11 | 12 | # METHODS 13 | 14 | sub default { 15 | return '0.0'; 16 | } 17 | 18 | 1; 19 | -------------------------------------------------------------------------------- /lib/Venus/Kind.pm: -------------------------------------------------------------------------------- 1 | package Venus::Kind; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Class 'with'; 9 | 10 | with 'Venus::Role::Boxable'; 11 | with 'Venus::Role::Tryable'; 12 | with 'Venus::Role::Catchable'; 13 | with 'Venus::Role::Comparable'; 14 | with 'Venus::Role::Deferrable'; 15 | with 'Venus::Role::Dumpable'; 16 | with 'Venus::Role::Digestable'; 17 | with 'Venus::Role::Doable'; 18 | with 'Venus::Role::Matchable'; 19 | with 'Venus::Role::Printable'; 20 | with 'Venus::Role::Reflectable'; 21 | with 'Venus::Role::Testable'; 22 | with 'Venus::Role::Throwable'; 23 | with 'Venus::Role::Assertable'; 24 | with 'Venus::Role::Serializable'; 25 | with 'Venus::Role::Mockable'; 26 | with 'Venus::Role::Patchable'; 27 | 28 | # METHODS 29 | 30 | sub checksum { 31 | my ($self) = @_; 32 | 33 | return $self->digest('md5', 'stringified'); 34 | } 35 | 36 | sub comparer { 37 | my ($self, $operation) = @_; 38 | 39 | if (lc($operation) eq 'eq') { 40 | return 'checksum'; 41 | } 42 | if (lc($operation) eq 'gt') { 43 | return 'numified'; 44 | } 45 | if (lc($operation) eq 'lt') { 46 | return 'numified'; 47 | } 48 | else { 49 | return 'stringified'; 50 | } 51 | } 52 | 53 | sub numified { 54 | my ($self) = @_; 55 | 56 | return CORE::length($self->stringified); 57 | } 58 | 59 | sub renew { 60 | my ($self, @args) = @_; 61 | 62 | my $data = $self->ARGS(@args); 63 | 64 | for my $attr (@{$self->meta->attrs}) { 65 | $data->{$attr} = $self->$attr if exists $self->{$attr} && !exists $data->{$attr}; 66 | } 67 | 68 | return $self->class->new($data); 69 | } 70 | 71 | sub safe { 72 | my ($self, $method, @args) = @_; 73 | 74 | my $result = $self->trap($method, @args); 75 | 76 | return(wantarray ? (@$result) : $result->[0]); 77 | } 78 | 79 | sub self { 80 | my ($self) = @_; 81 | 82 | return $self; 83 | } 84 | 85 | sub stringified { 86 | my ($self) = @_; 87 | 88 | return $self->dump($self->can('value') ? 'value' : ()); 89 | } 90 | 91 | sub trap { 92 | my ($self, $method, @args) = @_; 93 | 94 | no strict; 95 | no warnings; 96 | 97 | my $result = [[],[],[]]; 98 | 99 | return(wantarray ? (@$result) : $result->[0]) if !$method; 100 | 101 | local ($!, $?, $@, $^E); 102 | 103 | local $SIG{__DIE__} = sub{ 104 | push @{$result->[2]}, @_; 105 | }; 106 | 107 | local $SIG{__WARN__} = sub{ 108 | push @{$result->[1]}, @_; 109 | }; 110 | 111 | push @{$result->[0]}, eval { 112 | local $_ = $self; 113 | $self->$method(@args); 114 | }; 115 | 116 | return(wantarray ? (@$result) : $result->[0]); 117 | } 118 | 119 | 1; 120 | -------------------------------------------------------------------------------- /lib/Venus/Kind/Utility.pm: -------------------------------------------------------------------------------- 1 | package Venus::Kind::Utility; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Class 'base', 'with'; 9 | 10 | base 'Venus::Kind'; 11 | 12 | with 'Venus::Role::Buildable'; 13 | 14 | # BUILDERS 15 | 16 | sub build_arg { 17 | my ($self, $data) = @_; 18 | 19 | return { 20 | value => $data, 21 | }; 22 | } 23 | 24 | 1; 25 | -------------------------------------------------------------------------------- /lib/Venus/Kind/Utility.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Kind::Utility - Utility Base Class 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Utility Base Class for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package Example; 17 | 18 | use Venus::Class; 19 | 20 | base 'Venus::Kind::Utility'; 21 | 22 | package main; 23 | 24 | my $example = Example->new; 25 | 26 | =cut 27 | 28 | =head1 DESCRIPTION 29 | 30 | This package provides identity and methods common across all L utility 31 | classes. 32 | 33 | =cut 34 | 35 | =head1 INHERITS 36 | 37 | This package inherits behaviors from: 38 | 39 | L 40 | 41 | =cut 42 | 43 | =head1 INTEGRATES 44 | 45 | This package integrates behaviors from: 46 | 47 | L 48 | 49 | =cut 50 | 51 | =head1 AUTHORS 52 | 53 | Awncorp, C 54 | 55 | =cut 56 | 57 | =head1 LICENSE 58 | 59 | Copyright (C) 2000, Awncorp, C. 60 | 61 | This program is free software, you can redistribute it and/or modify it under 62 | the terms of the Apache license version 2.0. 63 | 64 | =cut -------------------------------------------------------------------------------- /lib/Venus/Kind/Value.pm: -------------------------------------------------------------------------------- 1 | package Venus::Kind::Value; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use overload ( 9 | '""' => 'explain', 10 | '~~' => 'explain', 11 | fallback => 1, 12 | ); 13 | 14 | use Venus::Class 'base', 'with'; 15 | 16 | base 'Venus::Kind'; 17 | 18 | with 'Venus::Role::Valuable'; 19 | with 'Venus::Role::Buildable'; 20 | with 'Venus::Role::Accessible'; 21 | with 'Venus::Role::Explainable'; 22 | with 'Venus::Role::Proxyable'; 23 | with 'Venus::Role::Pluggable'; 24 | 25 | # BUILDERS 26 | 27 | sub build_arg { 28 | my ($self, $data) = @_; 29 | 30 | return { 31 | value => $data, 32 | }; 33 | } 34 | 35 | # METHODS 36 | 37 | sub cast { 38 | my ($self, @args) = @_; 39 | 40 | require Venus::Type; 41 | 42 | my $value = $self->can('value') ? $self->value : $self; 43 | 44 | return Venus::Type->new(value => $value)->cast(@args); 45 | } 46 | 47 | sub defined { 48 | my ($self) = @_; 49 | 50 | return CORE::defined($self->get) ? true : false; 51 | } 52 | 53 | sub explain { 54 | my ($self) = @_; 55 | 56 | return $self->get; 57 | } 58 | 59 | sub mutate { 60 | my ($self, $code, @args) = @_; 61 | 62 | return $self->set($self->$code(@args)); 63 | } 64 | 65 | sub TO_JSON { 66 | my ($self) = @_; 67 | 68 | return $self->get; 69 | } 70 | 71 | 1; 72 | -------------------------------------------------------------------------------- /lib/Venus/Prototype.pm: -------------------------------------------------------------------------------- 1 | package Venus::Prototype; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Class 'base', 'with'; 9 | 10 | base 'Venus::Kind::Utility'; 11 | 12 | with 'Venus::Role::Valuable'; 13 | with 'Venus::Role::Buildable'; 14 | with 'Venus::Role::Proxyable'; 15 | 16 | use Scalar::Util (); 17 | 18 | # HOOKS 19 | 20 | sub _clone { 21 | my ($data) = @_; 22 | 23 | if (!defined($data)) { 24 | return $data; 25 | } 26 | elsif (!Scalar::Util::blessed($data) && ref($data) eq 'HASH') { 27 | my $copy = {}; 28 | for my $key (keys %$data) { 29 | $copy->{$key} = _clone($data->{$key}); 30 | } 31 | return $copy; 32 | } 33 | elsif (!Scalar::Util::blessed($data) && ref($data) eq 'ARRAY') { 34 | my $copy = []; 35 | for (my $i = 0; $i < @$data; $i++) { 36 | $copy->[$i] = _copy($data->[$i]); 37 | } 38 | return $copy; 39 | } 40 | else { 41 | return $data; 42 | } 43 | } 44 | 45 | sub _value { 46 | my ($data) = @_; 47 | 48 | if (keys %$data == 1 && exists $data->{value}) { 49 | return $data->{value}; 50 | } 51 | else { 52 | return $data; 53 | } 54 | } 55 | 56 | # BUILDERS 57 | 58 | sub build_args { 59 | my ($self, $data) = @_; 60 | 61 | if (keys %$data == 1 && exists $data->{value}) { 62 | return _clone($data); 63 | } 64 | return { 65 | value => _clone($data) 66 | }; 67 | } 68 | 69 | sub build_proxy { 70 | my ($self, $package, $method, @args) = @_; 71 | 72 | # as a method/routine 73 | return sub { 74 | $self->{value}{"\&$method"}->($self, @args) 75 | } 76 | if defined $self->{value}{"\&$method"}; 77 | 78 | # as a property/attribute 79 | return sub { 80 | @args ? $self->{value}{"\$$method"} = $args[0] : $self->{value}{"\$$method"} 81 | } 82 | if exists $self->{value}{"\$$method"}; 83 | 84 | return undef; 85 | } 86 | 87 | # METHODS 88 | 89 | sub apply { 90 | my ($self, $data) = @_; 91 | 92 | $data ||= {}; 93 | 94 | return $self->do('value', _clone({%{_value($self)}, %{_value($data)}})); 95 | } 96 | 97 | sub call { 98 | my ($self, $method, @args) = @_; 99 | 100 | # as a method/routine 101 | return $self->{value}{"\&$method"}->($self, @args) 102 | if defined $self->{value}{"\&$method"}; 103 | 104 | # as a property/attribute 105 | return @args ? $self->{value}{"\$$method"} = $args[0] : $self->{value}{"\$$method"} 106 | if exists $self->{value}{"\$$method"}; 107 | } 108 | 109 | sub default { 110 | my ($self) = @_; 111 | 112 | return {}; 113 | } 114 | 115 | sub extend { 116 | my ($self, $data) = @_; 117 | 118 | $data ||= {}; 119 | 120 | return $self->class->new(_clone({%{_value($self)}, %{_value($data)}})); 121 | } 122 | 123 | sub get { 124 | my ($self, @args) = @_; 125 | 126 | return $self->value if !@args; 127 | 128 | my ($index) = @args; 129 | 130 | return $self->value->{$index}; 131 | } 132 | 133 | sub set { 134 | my ($self, @args) = @_; 135 | 136 | return $self->value if !@args; 137 | 138 | return $self->value(@args) if @args == 1 && ref $args[0] eq 'HASH'; 139 | 140 | my ($index, $value) = @args; 141 | 142 | return if not defined $index; 143 | 144 | return $self->value->{$index} = $value; 145 | } 146 | 147 | 1; 148 | -------------------------------------------------------------------------------- /lib/Venus/Regexp.pm: -------------------------------------------------------------------------------- 1 | package Venus::Regexp; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Class 'base'; 9 | 10 | base 'Venus::Kind::Value'; 11 | 12 | use overload ( 13 | 'eq' => sub{"$_[0]" eq "$_[1]"}, 14 | 'ne' => sub{"$_[0]" ne "$_[1]"}, 15 | 'qr' => sub{$_[0]->value}, 16 | fallback => 1, 17 | ); 18 | 19 | # METHODS 20 | 21 | sub assertion { 22 | my ($self) = @_; 23 | 24 | my $assert = $self->SUPER::assertion; 25 | 26 | $assert->clear->expression('regexp'); 27 | 28 | return $assert; 29 | } 30 | 31 | sub comparer { 32 | my ($self) = @_; 33 | 34 | return 'stringified'; 35 | } 36 | 37 | sub default { 38 | return qr//; 39 | } 40 | 41 | sub replace { 42 | my ($self, $string, $substr, $flags) = @_; 43 | 44 | require Venus::Replace; 45 | 46 | my $replace = Venus::Replace->new( 47 | regexp => $self->get, 48 | string => $string // '', 49 | substr => $substr // '', 50 | flags => $flags // '', 51 | ); 52 | 53 | return $replace->do('evaluate'); 54 | } 55 | 56 | sub search { 57 | my ($self, $string) = @_; 58 | 59 | require Venus::Search; 60 | 61 | my $search = Venus::Search->new( 62 | regexp => $self->get, 63 | string => $string // '', 64 | ); 65 | 66 | return $search->do('evaluate'); 67 | } 68 | 69 | 1; 70 | -------------------------------------------------------------------------------- /lib/Venus/Role/Accessible.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Accessible; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'fault'; 9 | 10 | # AUDITS 11 | 12 | sub AUDIT { 13 | my ($self, $from) = @_; 14 | 15 | if (!$from->isa('Venus::Core')) { 16 | fault "${self} requires ${from} to derive from Venus::Core"; 17 | } 18 | 19 | return $self; 20 | } 21 | 22 | # METHODS 23 | 24 | sub access { 25 | my ($self, $name, @args) = @_; 26 | 27 | return if !$name; 28 | 29 | return $self->$name(@args); 30 | } 31 | 32 | sub assign { 33 | my ($self, $name, $code, @args) = @_; 34 | 35 | return if !$name; 36 | return if !$code; 37 | 38 | return $self->access($name, $self->$code(@args)); 39 | } 40 | 41 | # EXPORTS 42 | 43 | sub EXPORT { 44 | ['access', 'assign'] 45 | } 46 | 47 | 1; 48 | -------------------------------------------------------------------------------- /lib/Venus/Role/Assertable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Assertable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'fault'; 9 | 10 | # METHODS 11 | 12 | sub assert { 13 | my ($self, $data) = @_; 14 | 15 | return $self->assertion->result($data); 16 | } 17 | 18 | sub assertion { 19 | my ($self) = @_; 20 | 21 | require Venus::Assert; 22 | 23 | my $class = ref $self || $self; 24 | 25 | my $assert = Venus::Assert->new($class); 26 | 27 | $assert->match('hashref')->format(sub{ 28 | $class->new($_) 29 | }); 30 | 31 | $assert->accept($class); 32 | 33 | return $assert; 34 | } 35 | 36 | sub check { 37 | my ($self, $data) = @_; 38 | 39 | return $self->assertion->valid($data); 40 | } 41 | 42 | sub coerce { 43 | my ($self, $data) = @_; 44 | 45 | return $self->assertion->coerce($data); 46 | } 47 | 48 | sub make { 49 | my ($self, $data) = @_; 50 | 51 | return UNIVERSAL::isa($data, ref $self || $self) 52 | ? $data 53 | : $self->assert($data); 54 | } 55 | 56 | # EXPORTS 57 | 58 | sub EXPORT { 59 | ['assert', 'assertion', 'check', 'coerce', 'make'] 60 | } 61 | 62 | 1; 63 | -------------------------------------------------------------------------------- /lib/Venus/Role/Boxable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Boxable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # METHODS 11 | 12 | sub box { 13 | my ($self, $method, @args) = @_; 14 | 15 | require Venus::Box; 16 | 17 | local $_ = $self; 18 | 19 | my $value = $method ? $self->$method(@args) : $self; 20 | 21 | return Venus::Box->new(value => $value); 22 | } 23 | 24 | # EXPORTS 25 | 26 | sub EXPORT { 27 | ['box'] 28 | } 29 | 30 | 1; 31 | -------------------------------------------------------------------------------- /lib/Venus/Role/Boxable.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Role::Boxable - Boxable Role 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Boxable Role for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package Example; 17 | 18 | use Venus::Class; 19 | 20 | with 'Venus::Role::Boxable'; 21 | 22 | attr 'text'; 23 | 24 | package main; 25 | 26 | my $example = Example->new(text => 'hello, world'); 27 | 28 | # $example->box('text')->lc->ucfirst->concat('.')->unbox->get; 29 | 30 | # "Hello, world." 31 | 32 | =cut 33 | 34 | =head1 DESCRIPTION 35 | 36 | This package modifies the consuming package and provides a method for boxing 37 | itself. This makes it possible to chain method calls across objects and values. 38 | 39 | =cut 40 | 41 | =head1 METHODS 42 | 43 | This package provides the following methods: 44 | 45 | =cut 46 | 47 | =head2 box 48 | 49 | box(string | coderef $method, any @args) (object) 50 | 51 | The box method returns the invocant boxed, i.e. encapsulated, using 52 | L. This method supports dispatching, i.e. providing a method name 53 | and arguments whose return value will be acted on by this method. 54 | 55 | I> 56 | 57 | =over 4 58 | 59 | =item box example 1 60 | 61 | package main; 62 | 63 | my $example = Example->new(text => 'hello, world'); 64 | 65 | my $box = $example->box; 66 | 67 | # bless({ value => bless(..., "Example") }, "Venus::Box") 68 | 69 | =back 70 | 71 | =over 4 72 | 73 | =item box example 2 74 | 75 | package main; 76 | 77 | my $example = Example->new(text => 'hello, world'); 78 | 79 | my $box = $example->box('text'); 80 | 81 | # bless({ value => bless(..., "Venus::String") }, "Venus::Box") 82 | 83 | # $example->box('text')->lc->ucfirst->concat('.')->unbox->get; 84 | 85 | =back 86 | 87 | =cut 88 | 89 | =head1 AUTHORS 90 | 91 | Awncorp, C 92 | 93 | =cut 94 | 95 | =head1 LICENSE 96 | 97 | Copyright (C) 2000, Awncorp, C. 98 | 99 | This program is free software, you can redistribute it and/or modify it under 100 | the terms of the Apache license version 2.0. 101 | 102 | =cut -------------------------------------------------------------------------------- /lib/Venus/Role/Buildable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Buildable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # BUILDERS 11 | 12 | sub BUILD { 13 | my ($self, $args) = @_; 14 | 15 | if ($self->can('build_self')) { 16 | $self->build_self($args); 17 | } 18 | 19 | return $self; 20 | } 21 | 22 | sub BUILDARGS { 23 | my ($self, @args) = @_; 24 | 25 | # build_nil accepts a single-arg (empty hash) 26 | my $present = @args == 1 && ref $args[0] eq 'HASH' && !%{$args[0]}; 27 | 28 | # empty hash argument 29 | if ($self->can('build_nil') && $present) { 30 | @args = ($self->build_nil($args[0])); 31 | } 32 | 33 | # build_arg accepts a single-arg (non-hash) 34 | my $inflate = @args == 1 && ref $args[0] ne 'HASH'; 35 | 36 | # single argument 37 | if ($self->can('build_arg') && $inflate) { 38 | @args = ($self->build_arg($args[0])); 39 | } 40 | 41 | # build_args should not accept a single-arg (non-hash) 42 | my $ignore = @args == 1 && ref $args[0] ne 'HASH'; 43 | 44 | # standard arguments 45 | if ($self->can('build_args') && !$ignore) { 46 | @args = ($self->build_args(@args == 1 ? $args[0] : {@args})); 47 | } 48 | 49 | return (@args); 50 | } 51 | 52 | # EXPORTS 53 | 54 | sub EXPORT { 55 | ['BUILDARGS'] 56 | } 57 | 58 | 1; 59 | -------------------------------------------------------------------------------- /lib/Venus/Role/Catchable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Catchable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'fault'; 9 | 10 | # AUDITS 11 | 12 | sub AUDIT { 13 | my ($self, $from) = @_; 14 | 15 | if (!$from->does('Venus::Role::Tryable')) { 16 | fault "${self} requires ${from} to consume Venus::Role::Tryable"; 17 | } 18 | 19 | return $self; 20 | } 21 | 22 | # METHODS 23 | 24 | sub catch { 25 | my ($self, $method, @args) = @_; 26 | 27 | my @result = $self->try($method, @args)->error(\my $error)->result; 28 | 29 | return wantarray ? ($error ? ($error, undef) : ($error, @result)) : $error; 30 | } 31 | 32 | sub maybe { 33 | my ($self, $method, @args) = @_; 34 | 35 | my @result = $self->try($method, @args)->error(\my $error)->result; 36 | 37 | return wantarray ? ($error ? (undef) : (@result)) : ($error ? undef : $result[0]); 38 | } 39 | 40 | # EXPORTS 41 | 42 | sub EXPORT { 43 | ['catch', 'maybe'] 44 | } 45 | 46 | 1; 47 | -------------------------------------------------------------------------------- /lib/Venus/Role/Coercible.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Coercible; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # BUILDERS 11 | 12 | sub BUILD { 13 | my ($self, $data) = @_; 14 | 15 | $data = $self->coercion($data); 16 | 17 | for my $name (keys %$data) { 18 | $self->{$name} = $data->{$name}; 19 | } 20 | 21 | return $self; 22 | }; 23 | 24 | # METHODS 25 | 26 | sub coercers { 27 | my ($self) = @_; 28 | 29 | return $self->can('coerce') ? $self->coerce : {}; 30 | } 31 | 32 | sub coerce_args { 33 | my ($self, $data, $spec) = @_; 34 | 35 | for my $name (grep exists($data->{$_}), sort keys %$spec) { 36 | $data->{$name} = $self->coerce_onto( 37 | $data, $name, $spec->{$name}, $data->{$name}, 38 | ); 39 | } 40 | 41 | return $data; 42 | } 43 | 44 | sub coerce_attr { 45 | my ($self, $name, @args) = @_; 46 | 47 | return $self->{$name} if !@args; 48 | 49 | return $self->{$name} = $self->coercion({$name, $args[0]})->{$name}; 50 | } 51 | 52 | sub coerce_into { 53 | my ($self, $class, $value) = @_; 54 | 55 | require Scalar::Util; 56 | require Venus::Space; 57 | 58 | $class = (my $space = Venus::Space->new($class))->load; 59 | 60 | my $name = lc $space->label; 61 | 62 | if (my $method = $self->can("coerce_into_${name}")) { 63 | return $self->$method($class, $value); 64 | } 65 | if (Scalar::Util::blessed($value) && $value->isa($class)) { 66 | return $value; 67 | } 68 | else { 69 | return $class->new($value); 70 | } 71 | } 72 | 73 | sub coerce_onto { 74 | my ($self, $data, $name, $class, $value) = @_; 75 | 76 | require Venus::Space; 77 | 78 | $class = Venus::Space->new($class)->load; 79 | 80 | $value = $data->{$name} if $#_ < 4; 81 | 82 | if (my $method = $self->can("coerce_${name}")) { 83 | return $data->{$name} = $self->$method(\&coerce_into, $class, $value); 84 | } 85 | else { 86 | return $data->{$name} = $self->coerce_into($class, $value); 87 | } 88 | } 89 | 90 | sub coercion { 91 | my ($self, $data) = @_; 92 | 93 | my $spec = $self->coercers; 94 | 95 | return $data if !%$spec; 96 | 97 | return $self->coerce_args($data, $spec); 98 | } 99 | 100 | # EXPORTS 101 | 102 | sub EXPORT { 103 | [ 104 | 'coerce_args', 105 | 'coerce_attr', 106 | 'coerce_into', 107 | 'coerce_onto', 108 | 'coercers', 109 | 'coercion', 110 | ] 111 | } 112 | 113 | 1; 114 | -------------------------------------------------------------------------------- /lib/Venus/Role/Defaultable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Defaultable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # BUILDERS 11 | 12 | sub BUILD { 13 | my ($self) = @_; 14 | 15 | return $self if !$self->can('defaults'); 16 | 17 | my $defaults = $self->defaults; 18 | 19 | return $self if !$defaults; 20 | 21 | for my $name (@{$self->META->attrs}) { 22 | if (exists $defaults->{$name} && !exists $self->{$name}) { 23 | $self->{$name} = $defaults->{$name}; 24 | } 25 | } 26 | 27 | return $self; 28 | } 29 | 30 | 1; 31 | -------------------------------------------------------------------------------- /lib/Venus/Role/Defaultable.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Role::Defaultable - Defaultable Role 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Defaultable Role for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package Example; 17 | 18 | use Venus::Class 'attr', 'with'; 19 | 20 | with 'Venus::Role::Defaultable'; 21 | 22 | attr 'name'; 23 | 24 | sub defaults { 25 | { 26 | name => 'example', 27 | } 28 | } 29 | 30 | package main; 31 | 32 | my $example = Example->new; 33 | 34 | # bless({name => 'example'}, "Example") 35 | 36 | =cut 37 | 38 | =head1 DESCRIPTION 39 | 40 | This package provides a mechanism for setting default values for missing 41 | constructor arguments. 42 | 43 | =cut 44 | 45 | =head1 AUTHORS 46 | 47 | Awncorp, C 48 | 49 | =cut 50 | 51 | =head1 LICENSE 52 | 53 | Copyright (C) 2000, Awncorp, C. 54 | 55 | This program is free software, you can redistribute it and/or modify it under 56 | the terms of the Apache license version 2.0. 57 | 58 | =cut -------------------------------------------------------------------------------- /lib/Venus/Role/Deferrable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Deferrable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'fault'; 9 | 10 | # METHODS 11 | 12 | sub defer { 13 | my ($self, $name, @args) = @_; 14 | 15 | return sub {$self} if !$name; 16 | 17 | my $code = $self->can($name) 18 | or fault "Unable to defer $name: can't find $name in @{[ref $self]}"; 19 | 20 | return sub {@_ = ($self, @args, @_); goto $code}; 21 | } 22 | 23 | # EXPORTS 24 | 25 | sub EXPORT { 26 | ['defer'] 27 | } 28 | 29 | 1; 30 | -------------------------------------------------------------------------------- /lib/Venus/Role/Deferrable.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Role::Deferrable - Deferrable Role 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Deferrable Role for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package Example; 17 | 18 | use Venus::Class; 19 | 20 | with 'Venus::Role::Deferrable'; 21 | 22 | sub test { 23 | my ($self, @args) = @_; 24 | 25 | return $self->okay(@args); 26 | } 27 | 28 | sub okay { 29 | my ($self, @args) = @_; 30 | 31 | return [@args]; 32 | } 33 | 34 | package main; 35 | 36 | my $example = Example->new; 37 | 38 | # my $code = $example->defer('test'); 39 | 40 | # sub {...} 41 | 42 | # $code->(); 43 | 44 | # [...] 45 | 46 | =cut 47 | 48 | =head1 DESCRIPTION 49 | 50 | This package provides a mechanism for returning callbacks (i.e. closures) that 51 | dispatches method calls. 52 | 53 | =cut 54 | 55 | =head1 METHODS 56 | 57 | This package provides the following methods: 58 | 59 | =cut 60 | 61 | =head2 defer 62 | 63 | defer(string $method, any @args) (coderef) 64 | 65 | The defer method returns the named method as a callback (i.e. closure) which 66 | dispatches to the method call specified. 67 | 68 | I> 69 | 70 | =over 4 71 | 72 | =item defer example 1 73 | 74 | # given: synopsis 75 | 76 | package main; 77 | 78 | $example = Example->new; 79 | 80 | # bless({}, 'Example') 81 | 82 | # my $result = $example->defer('test', 1..4); 83 | 84 | # $result->(); 85 | 86 | # [1..4] 87 | 88 | =back 89 | 90 | =over 4 91 | 92 | =item defer example 2 93 | 94 | # given: synopsis 95 | 96 | package main; 97 | 98 | $example = Example->new; 99 | 100 | # bless({}, 'Example') 101 | 102 | # my $result = $example->defer('test', 1..4); 103 | 104 | # $result->(1..4); 105 | 106 | # [1..4, 1..4] 107 | 108 | =back 109 | 110 | =over 4 111 | 112 | =item defer example 3 113 | 114 | # given: synopsis 115 | 116 | package main; 117 | 118 | $example = Example->new; 119 | 120 | # bless({}, 'Example') 121 | 122 | # my $result = $example->defer; 123 | 124 | # $result->(); 125 | 126 | # bless({}, 'Example') 127 | 128 | =back 129 | 130 | =cut 131 | 132 | =head1 AUTHORS 133 | 134 | Awncorp, C 135 | 136 | =cut 137 | 138 | =head1 LICENSE 139 | 140 | Copyright (C) 2000, Awncorp, C. 141 | 142 | This program is free software, you can redistribute it and/or modify it under 143 | the terms of the Apache license version 2.0. 144 | 145 | =cut -------------------------------------------------------------------------------- /lib/Venus/Role/Digestable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Digestable; 2 | 3 | use 5.014; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'fault'; 9 | 10 | # AUDITS 11 | 12 | sub AUDIT { 13 | my ($self, $from) = @_; 14 | 15 | if (!$from->does('Venus::Role::Dumpable')) { 16 | fault "${self} requires ${from} to consume Venus::Role::Dumpable"; 17 | } 18 | 19 | return $self; 20 | } 21 | 22 | # METHODS 23 | 24 | sub digester { 25 | my ($self, $algorithm, $method, @args) = @_; 26 | 27 | my $result = $self->dump($method, @args); 28 | 29 | require Digest; 30 | 31 | my $digest = Digest->new(uc($algorithm || 'sha-1')); 32 | 33 | return $digest->add($result); 34 | } 35 | 36 | sub digest { 37 | my ($self, $algorithm, $method, @args) = @_; 38 | 39 | return $self->hexdigest($algorithm, $method, @args); 40 | } 41 | 42 | sub b64digest { 43 | my ($self, $algorithm, $method, @args) = @_; 44 | 45 | return $self->digester($algorithm, $method, @args)->b64digest; 46 | } 47 | 48 | sub bindigest { 49 | my ($self, $algorithm, $method, @args) = @_; 50 | 51 | return $self->digester($algorithm, $method, @args)->digest; 52 | } 53 | 54 | sub hexdigest { 55 | my ($self, $algorithm, $method, @args) = @_; 56 | 57 | return $self->digester($algorithm, $method, @args)->hexdigest; 58 | } 59 | 60 | # EXPORTS 61 | 62 | sub EXPORT { 63 | ['digester', 'digest', 'b64digest', 'bindigest', 'hexdigest'] 64 | } 65 | 66 | 1; 67 | -------------------------------------------------------------------------------- /lib/Venus/Role/Doable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Doable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # METHODS 11 | 12 | sub do { 13 | my ($self, $code, @args) = @_; 14 | 15 | $code ||= sub{}; 16 | 17 | local $_ = $self; 18 | $self->$code(@args); 19 | 20 | return $self; 21 | } 22 | 23 | # EXPORTS 24 | 25 | sub EXPORT { 26 | ['do'] 27 | } 28 | 29 | 1; 30 | -------------------------------------------------------------------------------- /lib/Venus/Role/Doable.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Role::Doable - Doable Role 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Doable Role for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package Example; 17 | 18 | use Venus::Class; 19 | 20 | with 'Venus::Role::Doable'; 21 | 22 | attr 'time'; 23 | 24 | sub execute { 25 | return; 26 | } 27 | 28 | package main; 29 | 30 | my $example = Example->new; 31 | 32 | # $example->do(time => time)->execute; 33 | 34 | =cut 35 | 36 | =head1 DESCRIPTION 37 | 38 | This package modifies the consuming package and provides methods for chaining 39 | any chainable and non-chainable methods (by ignoring their return values). 40 | 41 | =cut 42 | 43 | =head1 METHODS 44 | 45 | This package provides the following methods: 46 | 47 | =cut 48 | 49 | =head2 do 50 | 51 | do(string | coderef $method, any @args) (object) 52 | 53 | The do method dispatches the method call or executes the callback and returns 54 | the invocant. This method supports dispatching, i.e. providing a method name 55 | and arguments whose return value will be acted on by this method. 56 | 57 | I> 58 | 59 | =over 4 60 | 61 | =item do example 1 62 | 63 | package main; 64 | 65 | my $example = Example->new; 66 | 67 | $example = $example->do(time => time); 68 | 69 | # bless({ time => 0000000000 }, "Example") 70 | 71 | # $example->execute; 72 | 73 | =back 74 | 75 | =cut 76 | 77 | =head1 AUTHORS 78 | 79 | Awncorp, C 80 | 81 | =cut 82 | 83 | =head1 LICENSE 84 | 85 | Copyright (C) 2000, Awncorp, C. 86 | 87 | This program is free software, you can redistribute it and/or modify it under 88 | the terms of the Apache license version 2.0. 89 | 90 | =cut -------------------------------------------------------------------------------- /lib/Venus/Role/Dumpable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Dumpable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # METHODS 11 | 12 | sub dump { 13 | my ($self, $method, @args) = @_; 14 | 15 | require Data::Dumper; 16 | 17 | no warnings 'once'; 18 | 19 | local $Data::Dumper::Indent = 0; 20 | local $Data::Dumper::Purity = 0; 21 | local $Data::Dumper::Quotekeys = 0; 22 | local $Data::Dumper::Deepcopy = 1; 23 | local $Data::Dumper::Deparse = 1; 24 | local $Data::Dumper::Sortkeys = 1; 25 | local $Data::Dumper::Terse = 1; 26 | local $Data::Dumper::Useqq = 1; 27 | 28 | local $_ = $self; 29 | 30 | my $data = Data::Dumper->Dump([ 31 | $method ? scalar($self->$method(@args)) : $self 32 | ]); 33 | 34 | $data =~ s/^"|"$//g; 35 | 36 | return $data; 37 | } 38 | 39 | sub dump_pretty { 40 | my ($self, $method, @args) = @_; 41 | 42 | require Data::Dumper; 43 | 44 | no warnings 'once'; 45 | 46 | local $Data::Dumper::Indent = 2; 47 | local $Data::Dumper::Trailingcomma = 0; 48 | local $Data::Dumper::Purity = 0; 49 | local $Data::Dumper::Pad = ''; 50 | local $Data::Dumper::Varname = 'VAR'; 51 | local $Data::Dumper::Useqq = 0; 52 | local $Data::Dumper::Terse = 1; 53 | local $Data::Dumper::Freezer = ''; 54 | local $Data::Dumper::Toaster = ''; 55 | local $Data::Dumper::Deepcopy = 1; 56 | local $Data::Dumper::Quotekeys = 0; 57 | local $Data::Dumper::Bless = 'bless'; 58 | local $Data::Dumper::Pair = ' => '; 59 | local $Data::Dumper::Maxdepth = 0; 60 | local $Data::Dumper::Maxrecurse = 1000; 61 | local $Data::Dumper::Useperl = 0; 62 | local $Data::Dumper::Sortkeys = 1; 63 | local $Data::Dumper::Deparse = 1; 64 | local $Data::Dumper::Sparseseen = 0; 65 | 66 | local $_ = $self; 67 | 68 | my $data = Data::Dumper->Dump([ 69 | $method ? scalar($self->$method(@args)) : $self 70 | ]); 71 | 72 | $data =~ s/^'|'$//g; 73 | 74 | chomp $data; 75 | 76 | return $data; 77 | } 78 | 79 | # EXPORTS 80 | 81 | sub EXPORT { 82 | ['dump', 'dump_pretty'] 83 | } 84 | 85 | 1; 86 | -------------------------------------------------------------------------------- /lib/Venus/Role/Dumpable.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Role::Dumpable - Dumpable Role 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Dumpable Role for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package Example; 17 | 18 | use Venus::Class; 19 | 20 | attr 'test'; 21 | 22 | with 'Venus::Role::Dumpable'; 23 | 24 | package main; 25 | 26 | my $example = Example->new(test => 123); 27 | 28 | # $example->dump; 29 | 30 | =cut 31 | 32 | =head1 DESCRIPTION 33 | 34 | This package modifies the consuming package and provides methods for dumping 35 | the object or the return value of a dispatched method call. 36 | 37 | =cut 38 | 39 | =head1 METHODS 40 | 41 | This package provides the following methods: 42 | 43 | =cut 44 | 45 | =head2 dump 46 | 47 | dump(string | coderef $method, any @args) (string) 48 | 49 | The dump method returns a string representation of the underlying data. This 50 | method supports dispatching, i.e. providing a method name and arguments whose 51 | return value will be acted on by this method. 52 | 53 | I> 54 | 55 | =over 4 56 | 57 | =item dump example 1 58 | 59 | package main; 60 | 61 | my $example = Example->new(test => 123); 62 | 63 | my $dump = $example->dump; 64 | 65 | # "bless( {test => 123}, 'Example' )" 66 | 67 | =back 68 | 69 | =cut 70 | 71 | =head2 dump_pretty 72 | 73 | dump_pretty(string | coderef $method, any @args) (string) 74 | 75 | The dump_pretty method returns a string representation of the underlying data 76 | that is human-readable and useful for debugging. This method supports 77 | dispatching, i.e. providing a method name and arguments whose return value will 78 | be acted on by this method. 79 | 80 | I> 81 | 82 | =over 4 83 | 84 | =item dump_pretty example 1 85 | 86 | package main; 87 | 88 | my $example = Example->new(test => 123); 89 | 90 | my $dump_pretty = $example->dump_pretty; 91 | 92 | # bless( { 93 | # test => 123 94 | # }, 'Example' ) 95 | 96 | =back 97 | 98 | =cut 99 | 100 | =head1 AUTHORS 101 | 102 | Awncorp, C 103 | 104 | =cut 105 | 106 | =head1 LICENSE 107 | 108 | Copyright (C) 2000, Awncorp, C. 109 | 110 | This program is free software, you can redistribute it and/or modify it under 111 | the terms of the Apache license version 2.0. 112 | 113 | =cut -------------------------------------------------------------------------------- /lib/Venus/Role/Explainable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Explainable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'fault'; 9 | 10 | # AUDIT 11 | 12 | sub AUDIT { 13 | my ($self, $from) = @_; 14 | 15 | my $name = ref $self || $self; 16 | 17 | if (!$from->can('explain')) { 18 | fault "${from} requires 'explain' to consume ${name}"; 19 | } 20 | 21 | return $self; 22 | } 23 | 24 | 1; 25 | -------------------------------------------------------------------------------- /lib/Venus/Role/Explainable.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Role::Explainable - Explainable Role 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Explainable Role for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package Example; 17 | 18 | use Venus::Class; 19 | 20 | attr 'test'; 21 | 22 | sub explain { 23 | "okay" 24 | } 25 | 26 | with 'Venus::Role::Explainable'; 27 | 28 | package main; 29 | 30 | my $example = Example->new(test => 123); 31 | 32 | # $example->explain; 33 | 34 | =cut 35 | 36 | =head1 DESCRIPTION 37 | 38 | This package modifies the consuming package and provides methods for making the 39 | object stringifiable. 40 | 41 | =cut 42 | 43 | =head1 METHODS 44 | 45 | This package provides the following methods: 46 | 47 | =cut 48 | 49 | =head2 explain 50 | 51 | explain() (any) 52 | 53 | The explain method takes no arguments and returns the value to be used in 54 | stringification operations. 55 | 56 | I> 57 | 58 | =over 4 59 | 60 | =item explain example 1 61 | 62 | package main; 63 | 64 | my $example = Example->new(test => 123); 65 | 66 | my $explain = $example->explain; 67 | 68 | # "okay" 69 | 70 | =back 71 | 72 | =cut 73 | 74 | =head1 AUTHORS 75 | 76 | Awncorp, C 77 | 78 | =cut 79 | 80 | =head1 LICENSE 81 | 82 | Copyright (C) 2000, Awncorp, C. 83 | 84 | This program is free software, you can redistribute it and/or modify it under 85 | the terms of the Apache license version 2.0. 86 | 87 | =cut -------------------------------------------------------------------------------- /lib/Venus/Role/Makeable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Makeable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # BUILDERS 11 | 12 | sub BUILD { 13 | my ($self, $data) = @_; 14 | 15 | $data = $self->making($data); 16 | 17 | for my $name (keys %$data) { 18 | $self->{$name} = $data->{$name}; 19 | } 20 | 21 | return $self; 22 | }; 23 | 24 | # METHODS 25 | 26 | sub makers { 27 | my ($self) = @_; 28 | 29 | return {}; 30 | } 31 | 32 | sub make_args { 33 | my ($self, $data, $spec) = @_; 34 | 35 | for my $name (grep exists($data->{$_}), sort keys %$spec) { 36 | $data->{$name} = $self->make_onto( 37 | $data, $name, $spec->{$name}, $data->{$name}, 38 | ); 39 | } 40 | 41 | return $data; 42 | } 43 | 44 | sub make_attr { 45 | my ($self, $name, @args) = @_; 46 | 47 | return $self->{$name} if !@args; 48 | 49 | return $self->{$name} = $self->making({$name, $args[0]})->{$name}; 50 | } 51 | 52 | sub make_into { 53 | my ($self, $class, $value) = @_; 54 | 55 | require Scalar::Util; 56 | require Venus::Space; 57 | 58 | $class = (my $space = Venus::Space->new($class))->load; 59 | 60 | my $name = lc $space->label; 61 | 62 | if (my $method = $self->can("make_into_${name}")) { 63 | return $self->$method($class, $value); 64 | } 65 | if (Scalar::Util::blessed($value) && $value->isa($class)) { 66 | return $value; 67 | } 68 | else { 69 | return $class->make($value); 70 | } 71 | } 72 | 73 | sub make_onto { 74 | my ($self, $data, $name, $class, $value) = @_; 75 | 76 | require Venus::Space; 77 | 78 | $class = Venus::Space->new($class)->load; 79 | 80 | $value = $data->{$name} if $#_ < 4; 81 | 82 | if (my $method = $self->can("make_${name}")) { 83 | return $data->{$name} = $self->$method(\&make_into, $class, $value); 84 | } 85 | else { 86 | return $data->{$name} = $self->make_into($class, $value); 87 | } 88 | } 89 | 90 | sub making { 91 | my ($self, $data) = @_; 92 | 93 | my $spec = $self->makers; 94 | 95 | return $data if !%$spec; 96 | 97 | return $self->make_args($data, $spec); 98 | } 99 | 100 | # EXPORTS 101 | 102 | sub EXPORT { 103 | [ 104 | 'make_args', 105 | 'make_attr', 106 | 'make_into', 107 | 'make_onto', 108 | 'makers', 109 | 'making', 110 | ] 111 | } 112 | 113 | 1; 114 | -------------------------------------------------------------------------------- /lib/Venus/Role/Mappable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Mappable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'fault'; 9 | 10 | # AUDIT 11 | 12 | sub AUDIT { 13 | my ($self, $from) = @_; 14 | 15 | my $name = ref $self || $self; 16 | 17 | if (!$from->can('all')) { 18 | fault "${from} requires 'all' to consume ${name}"; 19 | } 20 | 21 | if (!$from->can('any')) { 22 | fault "${from} requires 'any' to consume ${name}"; 23 | } 24 | 25 | if (!$from->can('call')) { 26 | fault "${from} requires 'call' to consume ${name}"; 27 | } 28 | 29 | if (!$from->can('count')) { 30 | fault "${from} requires 'count' to consume ${name}"; 31 | } 32 | 33 | if (!$from->can('delete')) { 34 | fault "${from} requires 'delete' to consume ${name}"; 35 | } 36 | 37 | if (!$from->can('each')) { 38 | fault "${from} requires 'each' to consume ${name}"; 39 | } 40 | 41 | if (!$from->can('empty')) { 42 | fault "${from} requires 'empty' to consume ${name}"; 43 | } 44 | 45 | if (!$from->can('exists')) { 46 | fault "${from} requires 'exists' to consume ${name}"; 47 | } 48 | 49 | if (!$from->can('grep')) { 50 | fault "${from} requires 'grep' to consume ${name}"; 51 | } 52 | 53 | if (!$from->can('iterator')) { 54 | fault "${from} requires 'iterator' to consume ${name}"; 55 | } 56 | 57 | if (!$from->can('keys')) { 58 | fault "${from} requires 'keys' to consume ${name}"; 59 | } 60 | 61 | if (!$from->can('map')) { 62 | fault "${from} requires 'map' to consume ${name}"; 63 | } 64 | 65 | if (!$from->can('none')) { 66 | fault "${from} requires 'none' to consume ${name}"; 67 | } 68 | 69 | if (!$from->can('one')) { 70 | fault "${from} requires 'one' to consume ${name}"; 71 | } 72 | 73 | if (!$from->can('pairs')) { 74 | fault "${from} requires 'pairs' to consume ${name}"; 75 | } 76 | 77 | if (!$from->can('random')) { 78 | fault "${from} requires 'random' to consume ${name}"; 79 | } 80 | 81 | if (!$from->can('reverse')) { 82 | fault "${from} requires 'reverse' to consume ${name}"; 83 | } 84 | 85 | if (!$from->can('slice')) { 86 | fault "${from} requires 'slice' to consume ${name}"; 87 | } 88 | 89 | return $self; 90 | } 91 | 92 | 1; 93 | -------------------------------------------------------------------------------- /lib/Venus/Role/Matchable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Matchable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # METHODS 11 | 12 | sub match { 13 | my ($self, $method, @args) = @_; 14 | 15 | require Venus::Match; 16 | 17 | local $_ = $self; 18 | 19 | my $match = Venus::Match->new($method ? scalar($self->$method(@args)) : $self); 20 | 21 | return $match; 22 | } 23 | 24 | # EXPORTS 25 | 26 | sub EXPORT { 27 | ['match'] 28 | } 29 | 30 | 1; 31 | -------------------------------------------------------------------------------- /lib/Venus/Role/Matchable.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Role::Matchable - Matchable Role 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Matchable Role for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package Example; 17 | 18 | use Venus::Class; 19 | 20 | with 'Venus::Role::Matchable'; 21 | 22 | attr 'active'; 23 | 24 | sub validate { 25 | my ($self) = @_; 26 | 27 | return $self->match->when('active')->then(true)->none(false); 28 | } 29 | 30 | package main; 31 | 32 | my $example = Example->new; 33 | 34 | # $example->validate->result; 35 | 36 | # 0 37 | 38 | =cut 39 | 40 | =head1 DESCRIPTION 41 | 42 | This package modifies the consuming package and provides a mechanism for 43 | assembling complex pattern matching operations. 44 | 45 | =cut 46 | 47 | =head1 METHODS 48 | 49 | This package provides the following methods: 50 | 51 | =cut 52 | 53 | =head2 match 54 | 55 | match(string | coderef $method, any @args) (Venus::Match) 56 | 57 | The match method returns a L object having the match value set to 58 | the invocant or the result of a dispatch. This method supports dispatching, 59 | i.e. providing a method name and arguments whose return value will be acted on 60 | by this method. 61 | 62 | I> 63 | 64 | =over 4 65 | 66 | =item match example 1 67 | 68 | package main; 69 | 70 | my $example = Example->new; 71 | 72 | my $match = $example->match; 73 | 74 | # bless({..., value => bless(..., 'Example')}, 'Venus::Match') 75 | 76 | =back 77 | 78 | =over 4 79 | 80 | =item match example 2 81 | 82 | package main; 83 | 84 | my $example = Example->new; 85 | 86 | my $match = $example->match('active'); 87 | 88 | # bless({..., value => undef}, 'Venus::Match') 89 | 90 | =back 91 | 92 | =over 4 93 | 94 | =item match example 3 95 | 96 | package main; 97 | 98 | my $example = Example->new(active => 1); 99 | 100 | my $match = $example->match('active'); 101 | 102 | # bless({..., value => 1}, 'Venus::Match') 103 | 104 | =back 105 | 106 | =cut 107 | 108 | =head1 AUTHORS 109 | 110 | Awncorp, C 111 | 112 | =cut 113 | 114 | =head1 LICENSE 115 | 116 | Copyright (C) 2000, Awncorp, C. 117 | 118 | This program is free software, you can redistribute it and/or modify it under 119 | the terms of the Apache license version 2.0. 120 | 121 | =cut -------------------------------------------------------------------------------- /lib/Venus/Role/Mockable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Mockable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # METHODS 11 | 12 | sub mock { 13 | my ($self, $name, $code) = @_; 14 | 15 | no strict 'refs'; 16 | no warnings 'redefine'; 17 | 18 | my $class = ref $self || $self; 19 | 20 | my $orig = $class->can($name); 21 | 22 | *{"${class}::${name}"} = my $mock = $code->($orig); 23 | 24 | return $mock; 25 | } 26 | 27 | # EXPORTS 28 | 29 | sub EXPORT { 30 | ['mock'] 31 | } 32 | 33 | 1; 34 | -------------------------------------------------------------------------------- /lib/Venus/Role/Mockable.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Role::Mockable - Mockable Role 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Mockable Role for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package Example; 17 | 18 | use Venus::Class 'with'; 19 | 20 | with 'Venus::Role::Mockable'; 21 | 22 | sub execute { 23 | [1..4]; 24 | } 25 | 26 | package main; 27 | 28 | my $example = Example->new; 29 | 30 | # my $mock = $example->mock(execute => sub { 31 | # my ($next) = @_; 32 | # 33 | # return sub { 34 | # [@{$next->()}, @_] 35 | # } 36 | # }); 37 | 38 | # sub { ... } 39 | 40 | =cut 41 | 42 | =head1 DESCRIPTION 43 | 44 | This package provides a mechanism for mocking subroutines. 45 | 46 | =cut 47 | 48 | =head1 METHODS 49 | 50 | This package provides the following methods: 51 | 52 | =cut 53 | 54 | =head2 mock 55 | 56 | mock(string $name, coderef $code) (coderef) 57 | 58 | The mock method mocks the subroutine specified using the callback given. The 59 | coderef provided will be passed the original subroutine coderef as its first 60 | argument. The coderef provided should always return a coderef that will serve 61 | as the subroutine mock. 62 | 63 | I> 64 | 65 | =over 4 66 | 67 | =item mock example 1 68 | 69 | package main; 70 | 71 | my $example = Example->new; 72 | 73 | my $mock = $example->mock(execute => sub { 74 | my ($next) = @_; 75 | 76 | return sub { 77 | [@{$next->()}, @_] 78 | } 79 | }); 80 | 81 | # sub { ... } 82 | 83 | # $example->execute; 84 | 85 | # [1..4] 86 | 87 | # $example->execute(5, 6); 88 | 89 | # [1..6] 90 | 91 | =back 92 | 93 | =cut 94 | 95 | =head1 AUTHORS 96 | 97 | Awncorp, C 98 | 99 | =cut 100 | 101 | =head1 LICENSE 102 | 103 | Copyright (C) 2000, Awncorp, C. 104 | 105 | This program is free software, you can redistribute it and/or modify it under 106 | the terms of the Apache license version 2.0. 107 | 108 | =cut -------------------------------------------------------------------------------- /lib/Venus/Role/Patchable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Patchable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # METHODS 11 | 12 | sub patch { 13 | my ($self, $name, $code) = @_; 14 | 15 | require Venus::Space; 16 | 17 | my $space = Venus::Space->new(ref $self || $self); 18 | 19 | return $space->patch($name, $code); 20 | } 21 | 22 | # EXPORTS 23 | 24 | sub EXPORT { 25 | ['patch'] 26 | } 27 | 28 | 1; 29 | -------------------------------------------------------------------------------- /lib/Venus/Role/Patchable.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Role::Patchable - Patchable Role 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Patchable Role for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package Example; 17 | 18 | use Venus::Class; 19 | 20 | with 'Venus::Role::Patchable'; 21 | 22 | package main; 23 | 24 | my $example = Example->new; 25 | 26 | # my $patch = $example->patch; 27 | 28 | # bless(.., "Venus::Space") 29 | 30 | =cut 31 | 32 | =head1 DESCRIPTION 33 | 34 | This package modifies the consuming package and provides methods for patching 35 | (or monkey-patching) routines in the calling package using 36 | L. 37 | 38 | =cut 39 | 40 | =head1 METHODS 41 | 42 | This package provides the following methods: 43 | 44 | =cut 45 | 46 | =head2 patch 47 | 48 | patch(string $name, coderef $code) (Venus::Space) 49 | 50 | The patch method overwrites the named subroutine in the calling package using 51 | L returning a L object that can be used to 52 | restore the original subroutine when L is called. 53 | 54 | I> 55 | 56 | =over 4 57 | 58 | =item patch example 1 59 | 60 | package Example; 61 | 62 | use Venus::Class; 63 | 64 | with 'Venus::Role::Patchable'; 65 | 66 | sub test { 67 | my ($self, @args) = @_; 68 | 69 | return [$self, @args]; 70 | } 71 | 72 | package main; 73 | 74 | my $example = Example->new; 75 | 76 | my $patch = $example->patch('test', sub { 77 | my ($next, @args) = @_; 78 | 79 | return ['patched', @{$next->(@args)}]; 80 | }); 81 | 82 | # bless(.., "Venus::Space") 83 | 84 | =back 85 | 86 | =cut 87 | 88 | =head1 AUTHORS 89 | 90 | Awncorp, C 91 | 92 | =cut 93 | 94 | =head1 LICENSE 95 | 96 | Copyright (C) 2000, Awncorp, C. 97 | 98 | This program is free software, you can redistribute it and/or modify it under 99 | the terms of the Apache license version 2.0. 100 | 101 | =cut -------------------------------------------------------------------------------- /lib/Venus/Role/Pluggable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Pluggable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'fault'; 9 | 10 | # AUDITS 11 | 12 | sub AUDIT { 13 | my ($self, $from) = @_; 14 | 15 | if (!$from->does('Venus::Role::Proxyable')) { 16 | fault "${self} requires ${from} to consume Venus::Role::Proxyable"; 17 | } 18 | 19 | return $self; 20 | } 21 | 22 | # METHODS 23 | 24 | sub build_proxy { 25 | my ($self, $package, $method, @args) = @_; 26 | 27 | require Venus::Space; 28 | 29 | my $space = Venus::Space->new($package)->child('plugin', $method); 30 | 31 | return undef if !$space->tryload; 32 | 33 | return sub { 34 | if ($space->package->can('construct')) { 35 | my $class = $space->load; 36 | 37 | return $class->construct($self, @args)->execute; 38 | } 39 | else { 40 | my $class = $space->load; 41 | 42 | return $class->new->execute($self, @args); 43 | } 44 | }; 45 | } 46 | 47 | # EXPORTS 48 | 49 | sub EXPORT { 50 | ['build_proxy'] 51 | } 52 | 53 | 1; 54 | -------------------------------------------------------------------------------- /lib/Venus/Role/Pluggable.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Role::Pluggable - Pluggable Role 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Pluggable Role for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package Example::Plugin::Username; 17 | 18 | use Venus::Class; 19 | 20 | use Digest::SHA (); 21 | 22 | sub execute { 23 | my ($self, $example) = @_; 24 | 25 | return Digest::SHA::sha1_hex($example->login); 26 | } 27 | 28 | package Example::Plugin::Password; 29 | 30 | use Venus::Class; 31 | 32 | use Digest::SHA (); 33 | 34 | attr 'value'; 35 | 36 | sub construct { 37 | my ($class, $example) = @_; 38 | 39 | return $class->new(value => $example->secret); 40 | } 41 | 42 | sub execute { 43 | my ($self) = @_; 44 | 45 | return Digest::SHA::sha1_hex($self->value); 46 | } 47 | 48 | package Example; 49 | 50 | use Venus::Class; 51 | 52 | with 'Venus::Role::Proxyable'; 53 | with 'Venus::Role::Pluggable'; 54 | 55 | attr 'login'; 56 | attr 'secret'; 57 | 58 | package main; 59 | 60 | my $example = Example->new(login => 'admin', secret => 'p@ssw0rd'); 61 | 62 | # $example->username; 63 | # $example->password; 64 | 65 | =cut 66 | 67 | =head1 DESCRIPTION 68 | 69 | This package provides a mechanism for dispatching to plugin classes. 70 | 71 | =cut 72 | 73 | =head1 AUTHORS 74 | 75 | Awncorp, C 76 | 77 | =cut 78 | 79 | =head1 LICENSE 80 | 81 | Copyright (C) 2000, Awncorp, C. 82 | 83 | This program is free software, you can redistribute it and/or modify it under 84 | the terms of the Apache license version 2.0. 85 | 86 | =cut -------------------------------------------------------------------------------- /lib/Venus/Role/Proxyable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Proxyable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # METHODS 11 | 12 | sub AUTOLOAD { 13 | require Venus::Error; 14 | 15 | my ($package, $method) = our $AUTOLOAD =~ m[^(.+)::(.+)$]; 16 | 17 | my $build = $package->can('BUILDPROXY'); 18 | 19 | my $error = qq(Can't locate object method "$method" via package "$package"); 20 | 21 | Venus::Error->throw($error) unless $build && ref($build) eq 'CODE'; 22 | 23 | my $proxy = $build->($package, $method, @_); 24 | 25 | Venus::Error->throw($error) unless $proxy && ref($proxy) eq 'CODE'; 26 | 27 | goto &$proxy; 28 | } 29 | 30 | sub BUILDPROXY { 31 | require Venus::Error; 32 | 33 | my ($package, $method, $self, @args) = @_; 34 | 35 | my $build = $self->can('build_proxy'); 36 | 37 | return $build->($self, $package, $method, @args) if $build; 38 | 39 | my $error = qq(Can't locate object method "build_proxy" via package "$package"); 40 | 41 | Venus::Error->throw($error); 42 | } 43 | 44 | # EXPORTS 45 | 46 | sub EXPORT { 47 | ['AUTOLOAD', 'BUILDPROXY'] 48 | } 49 | 50 | 1; 51 | -------------------------------------------------------------------------------- /lib/Venus/Role/Proxyable.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Role::Proxyable - Proxyable Role 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Proxyable Role for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package Example; 17 | 18 | use Venus::Class; 19 | 20 | with 'Venus::Role::Proxyable'; 21 | 22 | attr 'test'; 23 | 24 | sub build_proxy { 25 | my ($self, $package, $method, @args) = @_; 26 | return sub { [$self, $package, $method, @args] } if $method eq 'anything'; 27 | return undef; 28 | } 29 | 30 | package main; 31 | 32 | my $example = Example->new(test => time); 33 | 34 | # $example->anything(1..4); 35 | 36 | =cut 37 | 38 | =head1 DESCRIPTION 39 | 40 | This package provides a hook into method dispatch resoluton via a wrapper 41 | around the C routine which processes calls to routines which don't 42 | exist. 43 | 44 | =cut 45 | 46 | =head1 METHODS 47 | 48 | This package provides the following methods: 49 | 50 | =cut 51 | 52 | =head2 build_proxy 53 | 54 | build_proxy(string $package, string $method, any @args) (coderef | undef) 55 | 56 | The build_proxy method should return a code reference to fulfill the method 57 | dispatching request, or undef to result in a method not found error. 58 | 59 | I> 60 | 61 | =over 4 62 | 63 | =item build_proxy example 1 64 | 65 | package main; 66 | 67 | my $example = Example->new(test => 123); 68 | 69 | my $build_proxy = $example->build_proxy('Example', 'everything', 1..4); 70 | 71 | # undef 72 | 73 | =back 74 | 75 | =over 4 76 | 77 | =item build_proxy example 2 78 | 79 | package main; 80 | 81 | my $example = Example->new(test => 123); 82 | 83 | my $build_proxy = $example->build_proxy('Example', 'anything', 1..4); 84 | 85 | # sub { ... } 86 | 87 | =back 88 | 89 | =cut 90 | 91 | =head1 AUTHORS 92 | 93 | Awncorp, C 94 | 95 | =cut 96 | 97 | =head1 LICENSE 98 | 99 | Copyright (C) 2000, Awncorp, C. 100 | 101 | This program is free software, you can redistribute it and/or modify it under 102 | the terms of the Apache license version 2.0. 103 | 104 | =cut -------------------------------------------------------------------------------- /lib/Venus/Role/Reflectable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Reflectable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # METHODS 11 | 12 | sub class { 13 | my ($self) = @_; 14 | 15 | return ref($self) || $self; 16 | } 17 | 18 | sub meta { 19 | my ($self) = @_; 20 | 21 | require Venus::Meta; 22 | 23 | return Venus::Meta->new(name => $self->class); 24 | } 25 | 26 | sub reify { 27 | my ($self, $method, @args) = @_; 28 | 29 | return $self->type($method, @args)->deduce; 30 | } 31 | 32 | sub space { 33 | my ($self) = @_; 34 | 35 | require Venus::Space; 36 | 37 | return Venus::Space->new($self->class); 38 | } 39 | 40 | sub type { 41 | my ($self, $method, @args) = @_; 42 | 43 | require Venus::Type; 44 | 45 | local $_ = $self; 46 | 47 | my $value = $method 48 | ? $self->$method(@args) : $self->can('value') ? $self->value : $self; 49 | 50 | return Venus::Type->new(value => $value); 51 | } 52 | 53 | # EXPORTS 54 | 55 | sub EXPORT { 56 | ['class', 'meta', 'reify', 'space', 'type'] 57 | } 58 | 59 | 1; 60 | -------------------------------------------------------------------------------- /lib/Venus/Role/Rejectable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Rejectable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # BUILDERS 11 | 12 | sub BUILD { 13 | my ($self) = @_; 14 | 15 | my %attrs = map +($_, $_), $self->META->attrs; 16 | my @unknowns = sort grep !exists($attrs{$_}), keys %$self; 17 | delete $self->{$_} for @unknowns; 18 | 19 | return $self; 20 | } 21 | 22 | 1; 23 | -------------------------------------------------------------------------------- /lib/Venus/Role/Rejectable.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Role::Rejectable - Rejectable Role 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Rejectable Role for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package ExampleAccept; 17 | 18 | use Venus::Class 'attr'; 19 | 20 | attr 'name'; 21 | 22 | package ExampleReject; 23 | 24 | use Venus::Class 'attr', 'with'; 25 | 26 | with 'Venus::Role::Rejectable'; 27 | 28 | attr 'name'; 29 | 30 | package main; 31 | 32 | my $example = ExampleReject->new(name => 'example', test => 12345); 33 | 34 | # bless({name => 'example'}, "Example") 35 | 36 | =cut 37 | 38 | =head1 DESCRIPTION 39 | 40 | This package provides a mechanism for rejecting unexpected constructor arguments. 41 | 42 | =cut 43 | 44 | =head1 AUTHORS 45 | 46 | Awncorp, C 47 | 48 | =cut 49 | 50 | =head1 LICENSE 51 | 52 | Copyright (C) 2000, Awncorp, C. 53 | 54 | This program is free software, you can redistribute it and/or modify it under 55 | the terms of the Apache license version 2.0. 56 | 57 | =cut -------------------------------------------------------------------------------- /lib/Venus/Role/Serializable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Serializable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # METHODS 11 | 12 | sub serialize { 13 | my ($self) = @_; 14 | 15 | if ( Scalar::Util::blessed($self) 16 | && $self->isa('Venus::Core') 17 | && $self->can('DOES') 18 | && $self->DOES('Venus::Role::Valuable')) 19 | { 20 | return deconstruct($self, $self->value); 21 | } 22 | 23 | if (UNIVERSAL::isa($self, 'ARRAY')) { 24 | return deconstruct($self, [@{$self}]); 25 | } 26 | 27 | if (UNIVERSAL::isa($self, 'CODE')) { 28 | return sub{goto \&$self}; 29 | } 30 | 31 | if (UNIVERSAL::isa($self, 'HASH')) { 32 | return deconstruct($self, {%{$self}}); 33 | } 34 | 35 | if (UNIVERSAL::isa($self, 'REF')) { 36 | return deconstruct($self, ${$self}); 37 | } 38 | 39 | if (UNIVERSAL::isa($self, 'REGEXP')) { 40 | return qr/$self/; 41 | } 42 | 43 | if (UNIVERSAL::isa($self, 'SCALAR')) { 44 | return deconstruct($self, ${$self}); 45 | } 46 | 47 | require Venus::Throw; 48 | my $throw = Venus::Throw->new(join('::', map ucfirst, ref($self), 'error')); 49 | $throw->name('on.serialize'); 50 | $throw->message("Can't serialize the object: $self"); 51 | $throw->stash(self => $self); 52 | $throw->error; 53 | } 54 | 55 | sub deconstruct { 56 | my ($self, $value) = @_; 57 | 58 | require Scalar::Util; 59 | 60 | if ( Scalar::Util::blessed($value) 61 | && $value->isa('Venus::Core') 62 | && $value->can('DOES') 63 | && $value->DOES('Venus::Role::Serializable')) 64 | { 65 | return $value->serialize; 66 | } 67 | 68 | if (UNIVERSAL::isa($value, 'CODE')) { 69 | return sub{goto \&$value}; 70 | } 71 | 72 | if (UNIVERSAL::isa($value, 'REF')) { 73 | return deconstruct($self, ${$value}); 74 | } 75 | 76 | if (UNIVERSAL::isa($value, 'REGEXP')) { 77 | return qr/$value/; 78 | } 79 | 80 | if (UNIVERSAL::isa($value, 'SCALAR')) { 81 | return deconstruct($self, ${$value}); 82 | } 83 | 84 | if (UNIVERSAL::isa($value, 'HASH')) { 85 | my $result = {}; 86 | for my $key (keys %{$value}) { 87 | $result->{$key} = deconstruct($self, $value->{$key}); 88 | } 89 | return $result; 90 | } 91 | 92 | if (UNIVERSAL::isa($value, 'ARRAY')) { 93 | my $result = []; 94 | for my $key (keys @{$value}) { 95 | $result->[$key] = deconstruct($self, $value->[$key]); 96 | } 97 | return $result; 98 | } 99 | 100 | if (Scalar::Util::blessed($value)) { 101 | require Venus::Throw; 102 | my $throw = Venus::Throw->new(join('::', map ucfirst, ref($self), 'error')); 103 | $throw->name('on.serialize.deconstruct'); 104 | $throw->message("Can't serialize properties in the object: $self"); 105 | $throw->stash(self => $self); 106 | $throw->error; 107 | } 108 | 109 | return $value; 110 | } 111 | 112 | # EXPORTS 113 | 114 | sub EXPORT { 115 | ['serialize'] 116 | } 117 | 118 | 1; 119 | -------------------------------------------------------------------------------- /lib/Venus/Role/Stashable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Stashable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # BUILDERS 11 | 12 | sub BUILD { 13 | my ($self, $data) = @_; 14 | 15 | $self->{'$stash'} = delete $data->{'$stash'} || {} if !$self->{'$stash'}; 16 | 17 | return $self; 18 | }; 19 | 20 | # METHODS 21 | 22 | sub stash { 23 | my ($self, $key, $value) = @_; 24 | 25 | return $self->{'$stash'} if !exists $_[1]; 26 | 27 | return $self->{'$stash'}->{$key} if !exists $_[2]; 28 | 29 | $self->{'$stash'}->{$key} = $value; 30 | 31 | return $value; 32 | } 33 | 34 | # EXPORTS 35 | 36 | sub EXPORT { 37 | ['stash'] 38 | } 39 | 40 | 1; 41 | -------------------------------------------------------------------------------- /lib/Venus/Role/Stashable.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Role::Stashable - Stashable Role 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Stashable Role for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package Example; 17 | 18 | use Venus::Class; 19 | 20 | with 'Venus::Role::Stashable'; 21 | 22 | attr 'test'; 23 | 24 | package main; 25 | 26 | my $example = Example->new(test => time); 27 | 28 | # $example->stash; 29 | 30 | =cut 31 | 32 | =head1 DESCRIPTION 33 | 34 | This package modifies the consuming package and provides methods for stashing 35 | data within the object. 36 | 37 | =cut 38 | 39 | =head1 METHODS 40 | 41 | This package provides the following methods: 42 | 43 | =cut 44 | 45 | =head2 stash 46 | 47 | stash(any $key, any $value) (any) 48 | 49 | The stash method is used to fetch and stash named values associated with the 50 | object. Calling this method without arguments returns all values. 51 | 52 | I> 53 | 54 | =over 4 55 | 56 | =item stash example 1 57 | 58 | package main; 59 | 60 | my $example = Example->new(test => time); 61 | 62 | my $stash = $example->stash; 63 | 64 | # {} 65 | 66 | =back 67 | 68 | =over 4 69 | 70 | =item stash example 2 71 | 72 | package main; 73 | 74 | my $example = Example->new(test => time); 75 | 76 | my $stash = $example->stash('test', {1..4}); 77 | 78 | # { 1 => 2, 3 => 4 } 79 | 80 | =back 81 | 82 | =over 4 83 | 84 | =item stash example 3 85 | 86 | package main; 87 | 88 | my $example = Example->new(test => time); 89 | 90 | my $stash = $example->stash('test'); 91 | 92 | # undef 93 | 94 | =back 95 | 96 | =cut 97 | 98 | =head1 AUTHORS 99 | 100 | Awncorp, C 101 | 102 | =cut 103 | 104 | =head1 LICENSE 105 | 106 | Copyright (C) 2000, Awncorp, C. 107 | 108 | This program is free software, you can redistribute it and/or modify it under 109 | the terms of the Apache license version 2.0. 110 | 111 | =cut -------------------------------------------------------------------------------- /lib/Venus/Role/Subscribable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Subscribable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # METHODS 11 | 12 | sub name { 13 | my ($name) = @_; 14 | 15 | $name = lc $name =~ s/\W+/_/gr if $name; 16 | 17 | return $name; 18 | } 19 | 20 | sub publish { 21 | my ($self, $name, @args) = @_; 22 | 23 | $name = name($name) or return $self; 24 | 25 | &$_(@args) for @{subscriptions($self)->{$name}}; 26 | 27 | return $self; 28 | } 29 | 30 | sub subscribe { 31 | my ($self, $name, $code) = @_; 32 | 33 | $name = name($name) or return $self; 34 | 35 | push @{subscriptions($self)->{$name}}, $code; 36 | 37 | return $self; 38 | } 39 | 40 | sub subscribers { 41 | my ($self, $name) = @_; 42 | 43 | $name = name($name) or return 0; 44 | 45 | if (exists subscriptions($self)->{$name}) { 46 | return 0+@{subscriptions($self)->{$name}}; 47 | } 48 | else { 49 | return 0; 50 | } 51 | } 52 | 53 | sub subscriptions { 54 | my ($self) = @_; 55 | 56 | return $self->{'$subscriptions'} ||= {}; 57 | } 58 | 59 | sub unsubscribe { 60 | my ($self, $name, $code) = @_; 61 | 62 | $name = name($name) or return $self; 63 | 64 | if ($code) { 65 | subscriptions($self)->{$name} = [ 66 | grep { $code ne $_ } @{subscriptions($self)->{$name}} 67 | ]; 68 | } 69 | else { 70 | delete subscriptions($self)->{$name}; 71 | } 72 | 73 | delete subscriptions($self)->{$name} if !$self->subscribers($name); 74 | 75 | return $self; 76 | } 77 | 78 | # EXPORTS 79 | 80 | sub EXPORT { 81 | ['publish', 'subscribe', 'subscribers', 'unsubscribe'] 82 | } 83 | 84 | 1; 85 | -------------------------------------------------------------------------------- /lib/Venus/Role/Superable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Superable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # METHODS 11 | 12 | sub super { 13 | require mro; 14 | goto \&next::method 15 | } 16 | 17 | # EXPORTS 18 | 19 | sub EXPORT { 20 | ['super'] 21 | } 22 | 23 | 1; 24 | -------------------------------------------------------------------------------- /lib/Venus/Role/Superable.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Role::Superable - Superable Role 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Superable Role for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package Example; 17 | 18 | use Venus::Class; 19 | 20 | with 'Venus::Role::Superable'; 21 | 22 | package main; 23 | 24 | my $example = Example->new; 25 | 26 | # $example->super; 27 | 28 | =cut 29 | 30 | =head1 DESCRIPTION 31 | 32 | This package modifies the consuming package and provides methods for 33 | dispatching to superclasses using L. 34 | 35 | =cut 36 | 37 | =head1 METHODS 38 | 39 | This package provides the following methods: 40 | 41 | =cut 42 | 43 | =head2 super 44 | 45 | super(any @args) (any) 46 | 47 | The super method dispatches to superclasses uses the C3 method resolution order 48 | to get better consistency in multiple inheritance situations. 49 | 50 | I> 51 | 52 | =over 4 53 | 54 | =item super example 1 55 | 56 | package Example::A; 57 | 58 | use Venus::Class; 59 | 60 | sub test { 61 | my ($self, @args) = @_; 62 | 63 | return [$self, @args]; 64 | } 65 | 66 | package Example::B; 67 | 68 | use Venus::Class; 69 | 70 | base 'Example::A'; 71 | 72 | with 'Venus::Role::Superable'; 73 | 74 | sub test { 75 | my ($self) = @_; 76 | 77 | return $self->super(1..4); 78 | } 79 | 80 | package main; 81 | 82 | my $example = Example::B->new; 83 | 84 | my $result = $example->test; 85 | 86 | =back 87 | 88 | =cut 89 | 90 | =head1 AUTHORS 91 | 92 | Awncorp, C 93 | 94 | =cut 95 | 96 | =head1 LICENSE 97 | 98 | Copyright (C) 2000, Awncorp, C. 99 | 100 | This program is free software, you can redistribute it and/or modify it under 101 | the terms of the Apache license version 2.0. 102 | 103 | =cut -------------------------------------------------------------------------------- /lib/Venus/Role/Testable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Testable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # METHODS 11 | 12 | sub is_false { 13 | my ($self, $code, @args) = @_; 14 | 15 | $code ||= $self->can('value') ? 'value' : sub{}; 16 | 17 | require Venus::Boolean; 18 | 19 | return $self->$code(@args) ? Venus::Boolean::FALSE() : Venus::Boolean::TRUE(); 20 | } 21 | 22 | sub is_true { 23 | my ($self, $code, @args) = @_; 24 | 25 | $code ||= $self->can('value') ? 'value' : sub{}; 26 | 27 | require Venus::Boolean; 28 | 29 | return $self->$code(@args) ? Venus::Boolean::TRUE() : Venus::Boolean::FALSE(); 30 | } 31 | 32 | # EXPORTS 33 | 34 | sub EXPORT { 35 | ['is_false', 'is_true'] 36 | } 37 | 38 | 1; 39 | -------------------------------------------------------------------------------- /lib/Venus/Role/Testable.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Role::Testable - Testable Role 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Testable Role for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package Example; 17 | 18 | use Venus::Class; 19 | 20 | with 'Venus::Role::Testable'; 21 | 22 | attr 'value'; 23 | 24 | sub execute { 25 | return pop; 26 | } 27 | 28 | package main; 29 | 30 | my $example = Example->new; 31 | 32 | # $example->is_true(sub{0}); 33 | 34 | =cut 35 | 36 | =head1 DESCRIPTION 37 | 38 | This package modifies the consuming package and provides methods for 39 | dispatching method calls and returning truthy returns as true and falsy returns 40 | as false boolean values. 41 | 42 | =cut 43 | 44 | =head1 METHODS 45 | 46 | This package provides the following methods: 47 | 48 | =cut 49 | 50 | =head2 is_false 51 | 52 | is_false(string | coderef $method, any @args) (boolean) 53 | 54 | The is_false method dispatches the method call or executes the callback and 55 | returns truthy returns as C and falsy returns as C 56 | L<"boolean"|Venus::Boolean> values. 57 | 58 | I> 59 | 60 | =over 4 61 | 62 | =item is_false example 1 63 | 64 | package main; 65 | 66 | my $example = Example->new; 67 | 68 | my $true = $example->is_false(execute => 0); 69 | 70 | # 1 71 | 72 | =back 73 | 74 | =over 4 75 | 76 | =item is_false example 2 77 | 78 | package main; 79 | 80 | my $example = Example->new; 81 | 82 | my $true = $example->is_false(sub{0}); 83 | 84 | # 1 85 | 86 | =back 87 | 88 | =over 4 89 | 90 | =item is_false example 3 91 | 92 | package main; 93 | 94 | my $example = Example->new; 95 | 96 | my $false = $example->is_false(execute => 1); 97 | 98 | # 0 99 | 100 | =back 101 | 102 | =cut 103 | 104 | =head2 is_true 105 | 106 | is_true(string | coderef $method, any @args) (boolean) 107 | 108 | The is_true method dispatches the method call or executes the callback and 109 | returns truthy returns as C and falsy returns as C 110 | L<"boolean"|Venus::Boolean> values. 111 | 112 | I> 113 | 114 | =over 4 115 | 116 | =item is_true example 1 117 | 118 | package main; 119 | 120 | my $example = Example->new; 121 | 122 | my $true = $example->is_true(execute => 1); 123 | 124 | # 1 125 | 126 | =back 127 | 128 | =over 4 129 | 130 | =item is_true example 2 131 | 132 | package main; 133 | 134 | my $example = Example->new; 135 | 136 | my $true = $example->is_true(sub{1}); 137 | 138 | # 1 139 | 140 | =back 141 | 142 | =over 4 143 | 144 | =item is_true example 3 145 | 146 | package main; 147 | 148 | my $example = Example->new; 149 | 150 | my $false = $example->is_true(execute => 0); 151 | 152 | # 0 153 | 154 | =back 155 | 156 | =cut 157 | 158 | =head1 AUTHORS 159 | 160 | Awncorp, C 161 | 162 | =cut 163 | 164 | =head1 LICENSE 165 | 166 | Copyright (C) 2000, Awncorp, C. 167 | 168 | This program is free software, you can redistribute it and/or modify it under 169 | the terms of the Apache license version 2.0. 170 | 171 | =cut -------------------------------------------------------------------------------- /lib/Venus/Role/Throwable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Throwable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # METHODS 11 | 12 | sub error { 13 | my ($self, $data) = @_; 14 | 15 | my @args = $data; 16 | 17 | unshift @args, delete $data->{throw} if $data->{throw}; 18 | 19 | @_ = ($self, @args); 20 | 21 | goto $self->can('throw'); 22 | } 23 | 24 | sub throw { 25 | my ($self, $data, @args) = @_; 26 | 27 | require Venus::Throw; 28 | 29 | my $throw = Venus::Throw->new(context => (caller(1))[3])->do( 30 | frame => 1, 31 | ); 32 | 33 | if (!$data) { 34 | return $throw->do( 35 | 'package', join('::', map ucfirst, ref($self), 'error') 36 | ); 37 | } 38 | if (ref $data ne 'HASH') { 39 | if ($data =~ /^\w+$/ && $self->can($data)) { 40 | $data = $self->$data(@args); 41 | } 42 | else { 43 | return $throw->do( 44 | 'package', $data, 45 | ); 46 | } 47 | } 48 | 49 | if (exists $data->{as}) { 50 | $throw->as($data->{as}); 51 | } 52 | if (exists $data->{capture}) { 53 | $throw->capture(@{$data->{capture}}); 54 | } 55 | if (exists $data->{context}) { 56 | $throw->context($data->{context}); 57 | } 58 | if (exists $data->{error}) { 59 | $throw->error($data->{error}); 60 | } 61 | if (exists $data->{frame}) { 62 | $throw->frame($data->{frame}); 63 | } 64 | if (exists $data->{message}) { 65 | $throw->message($data->{message}); 66 | } 67 | if (exists $data->{name}) { 68 | $throw->name($data->{name}); 69 | } 70 | if (exists $data->{package}) { 71 | $throw->package($data->{package}); 72 | } 73 | else { 74 | $throw->package(join('::', map ucfirst, ref($self), 'error')); 75 | } 76 | if (exists $data->{parent}) { 77 | $throw->parent($data->{parent}); 78 | } 79 | if (exists $data->{stash}) { 80 | $throw->stash($_, $data->{stash}->{$_}) for keys %{$data->{stash}}; 81 | } 82 | if (exists $data->{on}) { 83 | $throw->on($data->{on}); 84 | } 85 | if (exists $data->{raise}) { 86 | @_ = ($throw); 87 | goto $throw->can('error'); 88 | } 89 | 90 | return $throw; 91 | } 92 | 93 | # EXPORTS 94 | 95 | sub EXPORT { 96 | ['error', 'throw'] 97 | } 98 | 99 | 1; 100 | -------------------------------------------------------------------------------- /lib/Venus/Role/Tryable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Tryable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # METHODS 11 | 12 | sub try { 13 | my ($self, $callback, @args) = @_; 14 | 15 | require Venus::Try; 16 | 17 | my $try = Venus::Try->new(invocant => $self, arguments => [@args]); 18 | 19 | return $try if !$callback; 20 | 21 | return $try->call($callback); 22 | } 23 | 24 | # EXPORTS 25 | 26 | sub EXPORT { 27 | ['try'] 28 | } 29 | 30 | 1; 31 | -------------------------------------------------------------------------------- /lib/Venus/Role/Tryable.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Role::Tryable - Tryable Role 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Tryable Role for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package Example; 17 | 18 | use Venus::Class 'with'; 19 | use Venus 'raise'; 20 | 21 | with 'Venus::Role::Tryable'; 22 | 23 | sub test { 24 | raise 'Example::Error'; 25 | } 26 | 27 | package main; 28 | 29 | my $example = Example->new; 30 | 31 | # $example->try('test'); 32 | 33 | =cut 34 | 35 | =head1 DESCRIPTION 36 | 37 | This package modifies the consuming package and provides a mechanism for 38 | handling potentially volatile routines. 39 | 40 | =cut 41 | 42 | =head1 METHODS 43 | 44 | This package provides the following methods: 45 | 46 | =cut 47 | 48 | =head2 try 49 | 50 | try(string | coderef $method, any @args) (Venus::Try) 51 | 52 | The try method returns a L object having the invocant, callback, 53 | arguments pre-configured. This method supports dispatching, i.e. providing a 54 | method name and arguments whose return value will be acted on by this method. 55 | 56 | I> 57 | 58 | =over 4 59 | 60 | =item try example 1 61 | 62 | package main; 63 | 64 | my $example = Example->new; 65 | 66 | my $try = $example->try('test'); 67 | 68 | # my $value = $try->result; 69 | 70 | =back 71 | 72 | =cut 73 | 74 | =head1 AUTHORS 75 | 76 | Awncorp, C 77 | 78 | =cut 79 | 80 | =head1 LICENSE 81 | 82 | Copyright (C) 2000, Awncorp, C. 83 | 84 | This program is free software, you can redistribute it and/or modify it under 85 | the terms of the Apache license version 2.0. 86 | 87 | =cut -------------------------------------------------------------------------------- /lib/Venus/Role/Unacceptable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Unacceptable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'raise'; 9 | 10 | # BUILDERS 11 | 12 | sub BUILD { 13 | my ($self) = @_; 14 | 15 | my $class = ref $self || $self; 16 | my %attrs = map +($_, $_), $self->META->attrs; 17 | my @unknowns = sort grep !exists($attrs{$_}), keys %$self; 18 | 19 | raise 'Venus::Role::Unacceptable::Error', { 20 | name => 'on.build', 21 | '$stash' => {unknowns => [@unknowns]}, 22 | message => "$class was passed unknown attribute(s): " . join ', ', 23 | map "'$_'", @unknowns, 24 | } 25 | if @unknowns; 26 | 27 | return $self; 28 | } 29 | 30 | 1; 31 | -------------------------------------------------------------------------------- /lib/Venus/Role/Unacceptable.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Role::Unacceptable - Unacceptable Role 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Unacceptable Role for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package ExampleAccept; 17 | 18 | use Venus::Class 'attr'; 19 | 20 | attr 'name'; 21 | 22 | package ExampleDeny; 23 | 24 | use Venus::Class 'attr', 'with'; 25 | 26 | with 'Venus::Role::Unacceptable'; 27 | 28 | attr 'name'; 29 | 30 | package main; 31 | 32 | my $example = ExampleDeny->new(name => 'example', test => 12345); 33 | 34 | # Exception! (isa Venus::Role::Unacceptable::Error) 35 | 36 | =cut 37 | 38 | =head1 DESCRIPTION 39 | 40 | This package provides a mechanism for raising an exception when unexpected 41 | constructor arguments are encountered. 42 | 43 | =cut 44 | 45 | =head1 AUTHORS 46 | 47 | Awncorp, C 48 | 49 | =cut 50 | 51 | =head1 LICENSE 52 | 53 | Copyright (C) 2000, Awncorp, C. 54 | 55 | This program is free software, you can redistribute it and/or modify it under 56 | the terms of the Apache license version 2.0. 57 | 58 | =cut -------------------------------------------------------------------------------- /lib/Venus/Role/Unpackable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Unpackable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'with'; 9 | 10 | # METHODS 11 | 12 | sub unpack { 13 | my ($self, @args) = @_; 14 | 15 | require Venus::Unpack; 16 | 17 | my $name = (caller(1))[3] =~ s/.*::(\w+)$/$1/gr; 18 | 19 | return Venus::Unpack->from($self)->name($name)->do('args', @args)->all; 20 | } 21 | 22 | # EXPORTS 23 | 24 | sub EXPORT { 25 | ['unpack'] 26 | } 27 | 28 | 1; 29 | -------------------------------------------------------------------------------- /lib/Venus/Role/Unpackable.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Role::Unpackable - Unpackable Role 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Unpackable Role for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package Example; 17 | 18 | use Venus::Class; 19 | 20 | with 'Venus::Role::Unpackable'; 21 | 22 | sub execute { 23 | return shift; 24 | } 25 | 26 | package main; 27 | 28 | my $example = Example->new; 29 | 30 | # $example->unpack("hello", 123, 1.23)->signature( 31 | # 'string', 'number', 'float', 32 | # ); 33 | 34 | =cut 35 | 36 | =head1 DESCRIPTION 37 | 38 | This package modifies the consuming package and provides methods for unpacking 39 | and validating argument lists. 40 | 41 | =cut 42 | 43 | =head1 METHODS 44 | 45 | This package provides the following methods: 46 | 47 | =cut 48 | 49 | =head2 unpack 50 | 51 | unpack(any @args) (Venus::Unpack) 52 | 53 | The unpack method passes the arguments provided to L for 54 | unpacking and validating arbitrary argument lists. 55 | 56 | I> 57 | 58 | =over 4 59 | 60 | =item unpack example 1 61 | 62 | package main; 63 | 64 | my $example = Example->new; 65 | 66 | my $results = $example->unpack("hello", 123, 1.23)->signature( 67 | 'any', 68 | ); 69 | 70 | # ["hello", 123, 1.23] 71 | 72 | =back 73 | 74 | =over 4 75 | 76 | =item unpack example 2 77 | 78 | package main; 79 | 80 | my $example = Example->new; 81 | 82 | my $results = $example->unpack("hello", 123, 1.23)->signature( 83 | 'string', 84 | 'number | float', 85 | ); 86 | 87 | # ["hello", 123, 1.23] 88 | 89 | =back 90 | 91 | =over 4 92 | 93 | =item unpack example 3 94 | 95 | package main; 96 | 97 | my $example = Example->new; 98 | 99 | my $results = $example->unpack("hello", 123, 1.23)->signature( 100 | 'string', 101 | 'number', 102 | 'float', 103 | ); 104 | 105 | # ["hello", 123, 1.23] 106 | 107 | =back 108 | 109 | =cut 110 | 111 | =head1 AUTHORS 112 | 113 | Awncorp, C 114 | 115 | =cut 116 | 117 | =head1 LICENSE 118 | 119 | Copyright (C) 2000, Awncorp, C. 120 | 121 | This program is free software, you can redistribute it and/or modify it under 122 | the terms of the Apache license version 2.0. 123 | 124 | =cut -------------------------------------------------------------------------------- /lib/Venus/Role/Valuable.pm: -------------------------------------------------------------------------------- 1 | package Venus::Role::Valuable; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Role 'attr'; 9 | 10 | # ATTRIBUTES 11 | 12 | attr 'value'; 13 | 14 | # BUILDERS 15 | 16 | sub BUILD { 17 | my ($self, $data) = @_; 18 | 19 | $self->value($self->default) if !exists $data->{value}; 20 | } 21 | 22 | # METHODS 23 | 24 | sub default { 25 | 26 | return; 27 | } 28 | 29 | sub get { 30 | my ($self) = @_; 31 | 32 | return $self->value; 33 | } 34 | 35 | sub set { 36 | my ($self, $value) = @_; 37 | 38 | return $self->value($value); 39 | } 40 | 41 | # EXPORTS 42 | 43 | sub EXPORT { 44 | ['default', 'get', 'set', 'value'] 45 | } 46 | 47 | 1; 48 | -------------------------------------------------------------------------------- /lib/Venus/Role/Valuable.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::Role::Valuable - Valuable Role 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | Valuable Role for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package Example; 17 | 18 | use Venus::Class; 19 | 20 | with 'Venus::Role::Valuable'; 21 | 22 | package main; 23 | 24 | my $example = Example->new; 25 | 26 | # $example->value; 27 | 28 | =cut 29 | 30 | =head1 DESCRIPTION 31 | 32 | This package modifies the consuming package and provides a C attribute 33 | which defaults to what's returned by the C method, as well as C 34 | and C methods for modifying the value. 35 | 36 | =cut 37 | 38 | =head1 ATTRIBUTES 39 | 40 | This package has the following attributes: 41 | 42 | =cut 43 | 44 | =head2 value 45 | 46 | value(Any) 47 | 48 | This attribute is read-write, accepts C<(Any)> values, and is optional. 49 | 50 | =cut 51 | 52 | =head1 METHODS 53 | 54 | This package provides the following methods: 55 | 56 | =cut 57 | 58 | =head2 default 59 | 60 | default() (any) 61 | 62 | The default method returns the default value, i.e. C. 63 | 64 | I> 65 | 66 | =over 4 67 | 68 | =item default example 1 69 | 70 | package main; 71 | 72 | my $example = Example->new; 73 | 74 | my $default = $example->default; 75 | 76 | # undef 77 | 78 | =back 79 | 80 | =cut 81 | 82 | =head2 get 83 | 84 | get() (any) 85 | 86 | The get method gets and returns the value. 87 | 88 | I> 89 | 90 | =over 4 91 | 92 | =item get example 1 93 | 94 | package main; 95 | 96 | my $example = Example->new(value => 'hey, there'); 97 | 98 | my $get = $example->get; 99 | 100 | # "hey, there" 101 | 102 | =back 103 | 104 | =cut 105 | 106 | =head2 set 107 | 108 | set(any $value) (any) 109 | 110 | The set method set the value and returns the value set. 111 | 112 | I> 113 | 114 | =over 4 115 | 116 | =item set example 1 117 | 118 | package main; 119 | 120 | my $example = Example->new(value => 'hey, there'); 121 | 122 | my $set = $example->set('hi, there'); 123 | 124 | # "hi, there" 125 | 126 | =back 127 | 128 | =cut 129 | 130 | =head1 AUTHORS 131 | 132 | Awncorp, C 133 | 134 | =cut 135 | 136 | =head1 LICENSE 137 | 138 | Copyright (C) 2000, Awncorp, C. 139 | 140 | This program is free software, you can redistribute it and/or modify it under 141 | the terms of the Apache license version 2.0. 142 | 143 | =cut -------------------------------------------------------------------------------- /lib/Venus/Scalar.pm: -------------------------------------------------------------------------------- 1 | package Venus::Scalar; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Class 'base'; 9 | 10 | base 'Venus::Kind::Value'; 11 | 12 | use overload ( 13 | '${}' => sub{$_[0]->value}, 14 | '*{}' => sub{$_[0]->value}, 15 | fallback => 1, 16 | ); 17 | 18 | # METHODS 19 | 20 | sub assertion { 21 | my ($self) = @_; 22 | 23 | my $assertion = $self->SUPER::assertion; 24 | 25 | $assertion->match('scalarref')->format(sub{ 26 | (ref $self || $self)->new($_) 27 | }); 28 | 29 | return $assertion; 30 | } 31 | 32 | sub default { 33 | return \''; 34 | } 35 | 36 | 1; 37 | -------------------------------------------------------------------------------- /lib/Venus/Schema.pm: -------------------------------------------------------------------------------- 1 | package Venus::Schema; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Class 'attr', 'base'; 9 | 10 | base 'Venus::Kind::Utility'; 11 | 12 | # ATTRIBUTES 13 | 14 | attr 'definition'; 15 | 16 | # BUILDERS 17 | 18 | sub build_args { 19 | my ($self, $data) = @_; 20 | 21 | if (keys %$data == 1 && exists $data->{definition}) { 22 | return $data; 23 | } 24 | return { 25 | definition => $data, 26 | }; 27 | } 28 | 29 | # METHODS 30 | 31 | sub assert { 32 | my ($self) = @_; 33 | 34 | require Venus::Assert; 35 | 36 | my $assert = Venus::Assert->new; 37 | 38 | return $assert->expression($assert->render('hashkeys', $self->definition)); 39 | } 40 | 41 | sub check { 42 | my ($self, $data) = @_; 43 | 44 | my $assert = $self->assert; 45 | 46 | return $assert->valid($data); 47 | } 48 | 49 | sub deduce { 50 | my ($self, $data) = @_; 51 | 52 | require Venus::Type; 53 | 54 | my $assert = $self->assert; 55 | 56 | return Venus::Type->new($assert->validate($data))->deduce_deep; 57 | } 58 | 59 | sub error { 60 | my ($self, $data) = @_; 61 | 62 | my $error = $self->catch('validate', $data); 63 | 64 | die $error if $error && !$error->isa('Venus::Check::Error'); 65 | 66 | return $error; 67 | } 68 | 69 | sub validate { 70 | my ($self, $data) = @_; 71 | 72 | my $assert = $self->assert; 73 | 74 | return $assert->validate($data); 75 | } 76 | 77 | 1; 78 | -------------------------------------------------------------------------------- /lib/Venus/Sealed.pm: -------------------------------------------------------------------------------- 1 | package Venus::Sealed; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Class 'with'; 9 | 10 | with 'Venus::Role::Buildable'; 11 | with 'Venus::Role::Proxyable'; 12 | with 'Venus::Role::Tryable'; 13 | with 'Venus::Role::Throwable'; 14 | with 'Venus::Role::Catchable'; 15 | 16 | # BUILDERS 17 | 18 | sub build_arg { 19 | my ($self, $data) = @_; 20 | 21 | return { 22 | value => $data, 23 | }; 24 | } 25 | 26 | sub build_args { 27 | my ($self, $data) = @_; 28 | 29 | if (not(keys %$data == 1 && exists $data->{value})) { 30 | $data = (exists $data->{value}) ? {value => $data->{value}} : {}; 31 | } 32 | 33 | require Storable; 34 | 35 | $data = Storable::dclone($data); 36 | 37 | my $state = { 38 | (exists $data->{value} ? (value => $data->{value}) : ()) 39 | }; 40 | 41 | my $subs = { 42 | map +($_, $self->can($_)), grep /^__\w+$/, $self->meta->subs, 43 | }; 44 | 45 | my $scope = sub { 46 | my ($self, $name, @args) = @_; 47 | 48 | return if !$name; 49 | 50 | my $method = "__$name"; 51 | 52 | return if !$subs->{$method}; 53 | 54 | return $subs->{$method}->($self, $data, $state, @args); 55 | }; 56 | 57 | return { 58 | scope => $scope, 59 | }; 60 | } 61 | 62 | sub build_self { 63 | my ($self, $data) = @_; 64 | 65 | return $self; 66 | } 67 | 68 | sub build_proxy { 69 | my ($self, $package, $name, @args) = @_; 70 | 71 | my $method = $self->can("__$name"); 72 | 73 | if (!$method && ref $method ne 'CODE') { 74 | return undef; 75 | } 76 | 77 | return sub { 78 | return $self->{scope}->($self, $name, @args); 79 | }; 80 | } 81 | 82 | # METHODS 83 | 84 | sub __get { 85 | my ($self, $init, $data) = @_; 86 | 87 | return $data->{value}; 88 | } 89 | 90 | sub __set { 91 | my ($self, $init, $data, $value) = @_; 92 | 93 | return $data->{value} = $value; 94 | } 95 | 96 | 1; 97 | -------------------------------------------------------------------------------- /lib/Venus/True.pm: -------------------------------------------------------------------------------- 1 | package Venus::True; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Scalar::Util (); 9 | 10 | state $true = Scalar::Util::dualvar(1, "1"); 11 | 12 | use overload ( 13 | '!' => sub{!$true}, 14 | 'bool' => sub{$true}, 15 | fallback => 1, 16 | ); 17 | 18 | # METHODS 19 | 20 | sub new { 21 | return bless({}); 22 | } 23 | 24 | sub value { 25 | return $true; 26 | } 27 | 28 | 1; 29 | -------------------------------------------------------------------------------- /lib/Venus/True.pod: -------------------------------------------------------------------------------- 1 | 2 | =head1 NAME 3 | 4 | Venus::True - True Class 5 | 6 | =cut 7 | 8 | =head1 ABSTRACT 9 | 10 | True Class for Perl 5 11 | 12 | =cut 13 | 14 | =head1 SYNOPSIS 15 | 16 | package main; 17 | 18 | use Venus::True; 19 | 20 | my $true = Venus::True->new; 21 | 22 | # $true->value; 23 | 24 | =cut 25 | 26 | =head1 DESCRIPTION 27 | 28 | This package provides the global C value used in L and 29 | the L function. 30 | 31 | =cut 32 | 33 | =head1 METHODS 34 | 35 | This package provides the following methods: 36 | 37 | =cut 38 | 39 | =head2 value 40 | 41 | value() (boolean) 42 | 43 | The value method returns value representing the global C value. 44 | 45 | I> 46 | 47 | =over 4 48 | 49 | =item value example 1 50 | 51 | # given: synopsis; 52 | 53 | my $value = $true->value; 54 | 55 | # 1 56 | 57 | =back 58 | 59 | =cut 60 | 61 | =head1 AUTHORS 62 | 63 | Awncorp, C 64 | 65 | =cut 66 | 67 | =head1 LICENSE 68 | 69 | Copyright (C) 2000, Awncorp, C. 70 | 71 | This program is free software, you can redistribute it and/or modify it under 72 | the terms of the Apache license version 2.0. 73 | 74 | =cut -------------------------------------------------------------------------------- /lib/Venus/Undef.pm: -------------------------------------------------------------------------------- 1 | package Venus::Undef; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Class 'base'; 9 | 10 | base 'Venus::Kind::Value'; 11 | 12 | no overloading; 13 | 14 | # BUILDERS 15 | 16 | sub build_self { 17 | my ($self, $data) = @_; 18 | 19 | $self->{value} = undef; 20 | 21 | return $self; 22 | } 23 | 24 | # METHODS 25 | 26 | sub assertion { 27 | my ($self) = @_; 28 | 29 | my $assertion = $self->SUPER::assertion; 30 | 31 | $assertion->match('undef')->format(sub{ 32 | (ref $self || $self)->new 33 | }); 34 | 35 | return $assertion; 36 | } 37 | 38 | sub comparer { 39 | my ($self) = @_; 40 | 41 | return 'numified'; 42 | } 43 | 44 | sub default { 45 | 46 | return undef; 47 | } 48 | 49 | sub numified { 50 | my ($self) = @_; 51 | 52 | return 0; 53 | } 54 | 55 | sub stringified { 56 | my ($self) = @_; 57 | 58 | return ''; 59 | } 60 | 61 | 1; 62 | -------------------------------------------------------------------------------- /lib/Venus/Vars.pm: -------------------------------------------------------------------------------- 1 | package Venus::Vars; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Venus::Class 'attr', 'base', 'with'; 9 | 10 | base 'Venus::Kind::Utility'; 11 | 12 | with 'Venus::Role::Valuable'; 13 | with 'Venus::Role::Buildable'; 14 | with 'Venus::Role::Accessible'; 15 | with 'Venus::Role::Proxyable'; 16 | 17 | # ATTRIBUTES 18 | 19 | attr 'named'; 20 | 21 | # BUILDERS 22 | 23 | sub build_proxy { 24 | my ($self, $package, $method, $value) = @_; 25 | 26 | my $has_value = exists $_[3]; 27 | 28 | return sub { 29 | return $self->get($method) if !$has_value; # no value 30 | return $self->set($method, $value); 31 | }; 32 | } 33 | 34 | sub build_self { 35 | my ($self, $data) = @_; 36 | 37 | $self->named({}) if !$self->named; 38 | 39 | return $self; 40 | } 41 | 42 | # METHODS 43 | 44 | sub default { 45 | my ($self) = @_; 46 | 47 | return {%ENV}; 48 | } 49 | 50 | sub exists { 51 | my ($self, $name) = @_; 52 | 53 | return if not defined $name; 54 | 55 | my $pos = $self->name($name); 56 | 57 | return if not defined $pos; 58 | 59 | return exists $self->value->{$pos}; 60 | } 61 | 62 | sub get { 63 | my ($self, $name) = @_; 64 | 65 | return if not defined $name; 66 | 67 | my $pos = $self->name($name); 68 | 69 | return if not defined $pos; 70 | 71 | return $self->value->{$pos}; 72 | } 73 | 74 | sub name { 75 | my ($self, $name) = @_; 76 | 77 | if (defined $self->named->{$name}) { 78 | return $self->named->{$name}; 79 | } 80 | 81 | if (defined $self->value->{$name}) { 82 | return $name; 83 | } 84 | 85 | if (defined $self->value->{uc($name)}) { 86 | return uc($name); 87 | } 88 | 89 | return undef; 90 | } 91 | 92 | sub set { 93 | my ($self, $name, $data) = @_; 94 | 95 | return if not defined $name; 96 | 97 | my $pos = $self->name($name); 98 | 99 | return if not defined $pos; 100 | 101 | return $self->value->{$pos} = $data; 102 | } 103 | 104 | sub unnamed { 105 | my ($self) = @_; 106 | 107 | my $list = {}; 108 | 109 | my $vars = $self->value; 110 | my $data = +{reverse %{$self->named}}; 111 | 112 | for my $index (sort keys %$vars) { 113 | unless (exists $data->{$index}) { 114 | $list->{$index} = $vars->{$index}; 115 | } 116 | } 117 | 118 | return $list; 119 | } 120 | 121 | 1; 122 | -------------------------------------------------------------------------------- /shim/vns: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | package main; 4 | 5 | use 5.018; 6 | 7 | use strict; 8 | use warnings; 9 | 10 | use Cwd (); 11 | use File::Spec (); 12 | 13 | our $REPO; 14 | our @PATH; 15 | 16 | BEGIN { 17 | $ENV{VENUS_TASK_AUTO} = 1; 18 | $ENV{VENUS_TASK_NAME} = 'vns'; 19 | } 20 | 21 | BEGIN { 22 | @PATH = File::Spec->splitdir(Cwd::realpath($0)); 23 | $HOME = File::Spec->catfile(splice(@PATH, 0, -2), 'lib'); 24 | } 25 | 26 | use lib "$HOME"; 27 | 28 | use Venus::Run; 29 | 30 | 1; 31 | -------------------------------------------------------------------------------- /t/Venus_Box.t: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Test::More; 9 | use Venus::Test; 10 | 11 | my $test = test(__FILE__); 12 | 13 | =name 14 | 15 | Venus::Box 16 | 17 | =cut 18 | 19 | $test->for('name'); 20 | 21 | =tagline 22 | 23 | Box Class 24 | 25 | =cut 26 | 27 | $test->for('tagline'); 28 | 29 | =abstract 30 | 31 | Box Class for Perl 5 32 | 33 | =cut 34 | 35 | $test->for('abstract'); 36 | 37 | =includes 38 | 39 | method: unbox 40 | 41 | =cut 42 | 43 | $test->for('includes'); 44 | 45 | =synopsis 46 | 47 | package main; 48 | 49 | use Venus::Box; 50 | 51 | my $box = Venus::Box->new( 52 | value => {}, 53 | ); 54 | 55 | # $box->keys->count->unbox; 56 | 57 | =cut 58 | 59 | $test->for('synopsis', sub { 60 | my ($tryable) = @_; 61 | ok my $result = $tryable->result; 62 | ok $result->{value}->isa('Venus::Hash'); 63 | 64 | $result 65 | }); 66 | 67 | =description 68 | 69 | This package provides a pure Perl boxing mechanism for wrapping objects and 70 | values, and chaining method calls across all objects. 71 | 72 | =cut 73 | 74 | $test->for('description'); 75 | 76 | =integrates 77 | 78 | Venus::Role::Buildable 79 | Venus::Role::Proxyable 80 | 81 | =cut 82 | 83 | $test->for('integrates'); 84 | 85 | =method unbox 86 | 87 | The unbox method returns the un-boxed underlying object. This is a virtual 88 | method that dispatches to C<__handle__unbox>. This method supports dispatching, 89 | i.e. providing a method name and arguments whose return value will be acted on 90 | by this method. 91 | 92 | =signature unbox 93 | 94 | unbox(string $method, any @args) (any) 95 | 96 | =metadata unbox 97 | 98 | { 99 | since => '0.01', 100 | } 101 | 102 | =example-1 unbox 103 | 104 | # given: synopsis; 105 | 106 | my $unbox = $box->unbox; 107 | 108 | # bless({ value => {} }, "Venus::Hash") 109 | 110 | =cut 111 | 112 | $test->for('example', 1, 'unbox', sub { 113 | my ($tryable) = @_; 114 | ok my $result = $tryable->result; 115 | ok $result->isa('Venus::Hash'); 116 | 117 | $result 118 | }); 119 | 120 | =example-2 unbox 121 | 122 | # given: synopsis; 123 | 124 | my $unbox = $box->unbox('count'); 125 | 126 | # 0 127 | 128 | =cut 129 | 130 | $test->for('example', 2, 'unbox', sub { 131 | my ($tryable) = @_; 132 | ok !(my $result = $tryable->result); 133 | ok $result == 0; 134 | 135 | !$result 136 | }); 137 | 138 | =partials 139 | 140 | t/Venus.t: present: authors 141 | t/Venus.t: present: license 142 | 143 | =cut 144 | 145 | $test->for('partials'); 146 | 147 | # END 148 | 149 | $test->render('lib/Venus/Box.pod') if $ENV{VENUS_RENDER}; 150 | 151 | ok 1 and done_testing; -------------------------------------------------------------------------------- /t/Venus_False.t: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Test::More; 9 | use Venus::Test; 10 | 11 | my $test = test(__FILE__); 12 | 13 | =name 14 | 15 | Venus::False 16 | 17 | =cut 18 | 19 | $test->for('name'); 20 | 21 | =tagline 22 | 23 | False Class 24 | 25 | =cut 26 | 27 | $test->for('tagline'); 28 | 29 | =abstract 30 | 31 | False Class for Perl 5 32 | 33 | =cut 34 | 35 | $test->for('abstract'); 36 | 37 | =includes 38 | 39 | method: value 40 | 41 | =cut 42 | 43 | $test->for('includes'); 44 | 45 | =synopsis 46 | 47 | package main; 48 | 49 | use Venus::False; 50 | 51 | my $false = Venus::False->new; 52 | 53 | # $false->value; 54 | 55 | =cut 56 | 57 | $test->for('synopsis', sub { 58 | my ($tryable) = @_; 59 | ok !(my $result = $tryable->result); 60 | ok $result->isa('Venus::False'); 61 | 62 | !$result 63 | }); 64 | 65 | =description 66 | 67 | This package provides the global C value used in L and 68 | the L function. 69 | 70 | =cut 71 | 72 | $test->for('description'); 73 | 74 | =method value 75 | 76 | The value method returns value representing the global C value. 77 | 78 | =signature value 79 | 80 | value() (boolean) 81 | 82 | =metadata value 83 | 84 | { 85 | since => '1.23', 86 | } 87 | 88 | =example-1 value 89 | 90 | # given: synopsis; 91 | 92 | my $value = $false->value; 93 | 94 | # 0 95 | 96 | =cut 97 | 98 | $test->for('example', 1, 'value', sub { 99 | my ($tryable) = @_; 100 | ok !(my $result = $tryable->result); 101 | 102 | !$result 103 | }); 104 | 105 | =partials 106 | 107 | t/Venus.t: present: authors 108 | t/Venus.t: present: license 109 | 110 | =cut 111 | 112 | $test->for('partials'); 113 | 114 | # END 115 | 116 | $test->render('lib/Venus/False.pod') if $ENV{VENUS_RENDER}; 117 | 118 | ok 1 and done_testing; 119 | -------------------------------------------------------------------------------- /t/Venus_Kind_Utility.t: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Test::More; 9 | use Venus::Test; 10 | 11 | my $test = test(__FILE__); 12 | 13 | =name 14 | 15 | Venus::Kind::Utility 16 | 17 | =cut 18 | 19 | $test->for('name'); 20 | 21 | =tagline 22 | 23 | Utility Base Class 24 | 25 | =cut 26 | 27 | $test->for('tagline'); 28 | 29 | =abstract 30 | 31 | Utility Base Class for Perl 5 32 | 33 | =cut 34 | 35 | $test->for('abstract'); 36 | 37 | =synopsis 38 | 39 | package Example; 40 | 41 | use Venus::Class; 42 | 43 | base 'Venus::Kind::Utility'; 44 | 45 | package main; 46 | 47 | my $example = Example->new; 48 | 49 | =cut 50 | 51 | $test->for('synopsis', sub { 52 | my ($tryable) = @_; 53 | ok my $result = $tryable->result; 54 | ok $result->isa('Example'); 55 | 56 | $result 57 | }); 58 | 59 | =description 60 | 61 | This package provides identity and methods common across all L utility 62 | classes. 63 | 64 | =cut 65 | 66 | $test->for('description'); 67 | 68 | =inherits 69 | 70 | Venus::Kind 71 | 72 | =cut 73 | 74 | $test->for('inherits'); 75 | 76 | =integrates 77 | 78 | Venus::Role::Buildable 79 | 80 | =cut 81 | 82 | $test->for('integrates'); 83 | 84 | =partials 85 | 86 | t/Venus.t: present: authors 87 | t/Venus.t: present: license 88 | 89 | =cut 90 | 91 | $test->for('partials'); 92 | 93 | # END 94 | 95 | $test->render('lib/Venus/Kind/Utility.pod') if $ENV{VENUS_RENDER}; 96 | 97 | ok 1 and done_testing; -------------------------------------------------------------------------------- /t/Venus_Role_Boxable.t: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Test::More; 9 | use Venus::Test; 10 | 11 | my $test = test(__FILE__); 12 | 13 | =name 14 | 15 | Venus::Role::Boxable 16 | 17 | =cut 18 | 19 | $test->for('name'); 20 | 21 | =tagline 22 | 23 | Boxable Role 24 | 25 | =cut 26 | 27 | $test->for('tagline'); 28 | 29 | =abstract 30 | 31 | Boxable Role for Perl 5 32 | 33 | =cut 34 | 35 | $test->for('abstract'); 36 | 37 | =includes 38 | 39 | method: box 40 | 41 | =cut 42 | 43 | $test->for('includes'); 44 | 45 | =synopsis 46 | 47 | package Example; 48 | 49 | use Venus::Class; 50 | 51 | with 'Venus::Role::Boxable'; 52 | 53 | attr 'text'; 54 | 55 | package main; 56 | 57 | my $example = Example->new(text => 'hello, world'); 58 | 59 | # $example->box('text')->lc->ucfirst->concat('.')->unbox->get; 60 | 61 | # "Hello, world." 62 | 63 | =cut 64 | 65 | $test->for('synopsis', sub { 66 | my ($tryable) = @_; 67 | ok my $result = $tryable->result; 68 | ok $result->isa('Example'); 69 | ok $result->does('Venus::Role::Boxable'); 70 | 71 | $result 72 | }); 73 | 74 | =description 75 | 76 | This package modifies the consuming package and provides a method for boxing 77 | itself. This makes it possible to chain method calls across objects and values. 78 | 79 | =cut 80 | 81 | $test->for('description'); 82 | 83 | =method box 84 | 85 | The box method returns the invocant boxed, i.e. encapsulated, using 86 | L. This method supports dispatching, i.e. providing a method name 87 | and arguments whose return value will be acted on by this method. 88 | 89 | =signature box 90 | 91 | box(string | coderef $method, any @args) (object) 92 | 93 | =metadata box 94 | 95 | { 96 | since => '0.01', 97 | } 98 | 99 | =example-1 box 100 | 101 | package main; 102 | 103 | my $example = Example->new(text => 'hello, world'); 104 | 105 | my $box = $example->box; 106 | 107 | # bless({ value => bless(..., "Example") }, "Venus::Box") 108 | 109 | =cut 110 | 111 | $test->for('example', 1, 'box', sub { 112 | my ($tryable) = @_; 113 | ok my $result = $tryable->result; 114 | ok $result->isa('Venus::Box'); 115 | ok $result->{value}; 116 | ok $result->{value}->isa('Example'); 117 | 118 | $result 119 | }); 120 | 121 | =example-2 box 122 | 123 | package main; 124 | 125 | my $example = Example->new(text => 'hello, world'); 126 | 127 | my $box = $example->box('text'); 128 | 129 | # bless({ value => bless(..., "Venus::String") }, "Venus::Box") 130 | 131 | # $example->box('text')->lc->ucfirst->concat('.')->unbox->get; 132 | 133 | =cut 134 | 135 | $test->for('example', 2, 'box', sub { 136 | my ($tryable) = @_; 137 | ok my $result = $tryable->result; 138 | ok $result->isa('Venus::Box'); 139 | ok $result->{value}; 140 | ok $result->{value}->isa('Venus::String'); 141 | 142 | $result 143 | }); 144 | 145 | =partials 146 | 147 | t/Venus.t: present: authors 148 | t/Venus.t: present: license 149 | 150 | =cut 151 | 152 | $test->for('partials'); 153 | 154 | # END 155 | 156 | $test->render('lib/Venus/Role/Boxable.pod') if $ENV{VENUS_RENDER}; 157 | 158 | ok 1 and done_testing; -------------------------------------------------------------------------------- /t/Venus_Role_Defaultable.t: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Test::More; 9 | use Venus::Test; 10 | 11 | my $test = test(__FILE__); 12 | 13 | =name 14 | 15 | Venus::Role::Defaultable 16 | 17 | =cut 18 | 19 | $test->for('name'); 20 | 21 | =tagline 22 | 23 | Defaultable Role 24 | 25 | =cut 26 | 27 | $test->for('tagline'); 28 | 29 | =abstract 30 | 31 | Defaultable Role for Perl 5 32 | 33 | =cut 34 | 35 | $test->for('abstract'); 36 | 37 | =synopsis 38 | 39 | package Example; 40 | 41 | use Venus::Class 'attr', 'with'; 42 | 43 | with 'Venus::Role::Defaultable'; 44 | 45 | attr 'name'; 46 | 47 | sub defaults { 48 | { 49 | name => 'example', 50 | } 51 | } 52 | 53 | package main; 54 | 55 | my $example = Example->new; 56 | 57 | # bless({name => 'example'}, "Example") 58 | 59 | =cut 60 | 61 | $test->for('synopsis', sub { 62 | my ($tryable) = @_; 63 | ok my $result = $tryable->result; 64 | ok $result->isa('Example'); 65 | ok $result->does('Venus::Role::Defaultable'); 66 | is $result->{name}, 'example'; 67 | my $example = Example->new(name => 'another_example'); 68 | ok $example->isa('Example'); 69 | ok $example->does('Venus::Role::Defaultable'); 70 | is $example->{name}, 'another_example'; 71 | 72 | $result 73 | }); 74 | 75 | =description 76 | 77 | This package provides a mechanism for setting default values for missing 78 | constructor arguments. 79 | 80 | =cut 81 | 82 | $test->for('description'); 83 | 84 | =partials 85 | 86 | t/Venus.t: present: authors 87 | t/Venus.t: present: license 88 | 89 | =cut 90 | 91 | $test->for('partials'); 92 | 93 | # END 94 | 95 | $test->render('lib/Venus/Role/Defaultable.pod') if $ENV{VENUS_RENDER}; 96 | 97 | ok 1 and done_testing; 98 | -------------------------------------------------------------------------------- /t/Venus_Role_Doable.t: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Test::More; 9 | use Venus::Test; 10 | 11 | my $test = test(__FILE__); 12 | 13 | =name 14 | 15 | Venus::Role::Doable 16 | 17 | =cut 18 | 19 | $test->for('name'); 20 | 21 | =tagline 22 | 23 | Doable Role 24 | 25 | =cut 26 | 27 | $test->for('tagline'); 28 | 29 | =abstract 30 | 31 | Doable Role for Perl 5 32 | 33 | =cut 34 | 35 | $test->for('abstract'); 36 | 37 | =includes 38 | 39 | method: do 40 | 41 | =cut 42 | 43 | $test->for('includes'); 44 | 45 | =synopsis 46 | 47 | package Example; 48 | 49 | use Venus::Class; 50 | 51 | with 'Venus::Role::Doable'; 52 | 53 | attr 'time'; 54 | 55 | sub execute { 56 | return; 57 | } 58 | 59 | package main; 60 | 61 | my $example = Example->new; 62 | 63 | # $example->do(time => time)->execute; 64 | 65 | =cut 66 | 67 | $test->for('synopsis', sub { 68 | my ($tryable) = @_; 69 | ok my $result = $tryable->result; 70 | ok $result->isa('Example'); 71 | ok $result->does('Venus::Role::Doable'); 72 | 73 | $result 74 | }); 75 | 76 | =description 77 | 78 | This package modifies the consuming package and provides methods for chaining 79 | any chainable and non-chainable methods (by ignoring their return values). 80 | 81 | =cut 82 | 83 | $test->for('description'); 84 | 85 | =method do 86 | 87 | The do method dispatches the method call or executes the callback and returns 88 | the invocant. This method supports dispatching, i.e. providing a method name 89 | and arguments whose return value will be acted on by this method. 90 | 91 | =signature do 92 | 93 | do(string | coderef $method, any @args) (object) 94 | 95 | =metadata do 96 | 97 | { 98 | since => '0.01', 99 | } 100 | 101 | =example-1 do 102 | 103 | package main; 104 | 105 | my $example = Example->new; 106 | 107 | $example = $example->do(time => time); 108 | 109 | # bless({ time => 0000000000 }, "Example") 110 | 111 | # $example->execute; 112 | 113 | =cut 114 | 115 | $test->for('example', 1, 'do', sub { 116 | my ($tryable) = @_; 117 | ok my $result = $tryable->result; 118 | ok $result->isa('Example'); 119 | ok $result->time; 120 | 121 | $result 122 | }); 123 | 124 | =partials 125 | 126 | t/Venus.t: present: authors 127 | t/Venus.t: present: license 128 | 129 | =cut 130 | 131 | $test->for('partials'); 132 | 133 | # END 134 | 135 | $test->render('lib/Venus/Role/Doable.pod') if $ENV{VENUS_RENDER}; 136 | 137 | ok 1 and done_testing; -------------------------------------------------------------------------------- /t/Venus_Role_Explainable.t: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Test::More; 9 | use Venus::Test; 10 | 11 | my $test = test(__FILE__); 12 | 13 | =name 14 | 15 | Venus::Role::Explainable 16 | 17 | =cut 18 | 19 | $test->for('name'); 20 | 21 | =tagline 22 | 23 | Explainable Role 24 | 25 | =cut 26 | 27 | $test->for('tagline'); 28 | 29 | =abstract 30 | 31 | Explainable Role for Perl 5 32 | 33 | =cut 34 | 35 | $test->for('abstract'); 36 | 37 | =includes 38 | 39 | method: explain 40 | 41 | =cut 42 | 43 | $test->for('includes'); 44 | 45 | =synopsis 46 | 47 | package Example; 48 | 49 | use Venus::Class; 50 | 51 | attr 'test'; 52 | 53 | sub explain { 54 | "okay" 55 | } 56 | 57 | with 'Venus::Role::Explainable'; 58 | 59 | package main; 60 | 61 | my $example = Example->new(test => 123); 62 | 63 | # $example->explain; 64 | 65 | =cut 66 | 67 | $test->for('synopsis', sub { 68 | my ($tryable) = @_; 69 | ok my $result = $tryable->result; 70 | ok $result->isa('Example'); 71 | ok $result->does('Venus::Role::Explainable'); 72 | 73 | $result 74 | }); 75 | 76 | =description 77 | 78 | This package modifies the consuming package and provides methods for making the 79 | object stringifiable. 80 | 81 | =cut 82 | 83 | $test->for('description'); 84 | 85 | =method explain 86 | 87 | The explain method takes no arguments and returns the value to be used in 88 | stringification operations. 89 | 90 | =signature explain 91 | 92 | explain() (any) 93 | 94 | =metadata explain 95 | 96 | { 97 | since => '0.01', 98 | } 99 | 100 | =example-1 explain 101 | 102 | package main; 103 | 104 | my $example = Example->new(test => 123); 105 | 106 | my $explain = $example->explain; 107 | 108 | # "okay" 109 | 110 | =cut 111 | 112 | $test->for('example', 1, 'explain', sub { 113 | my ($tryable) = @_; 114 | ok my $result = $tryable->result; 115 | ok $result eq "okay"; 116 | 117 | $result 118 | }); 119 | 120 | =partials 121 | 122 | t/Venus.t: present: authors 123 | t/Venus.t: present: license 124 | 125 | =cut 126 | 127 | $test->for('partials'); 128 | 129 | # END 130 | 131 | $test->render('lib/Venus/Role/Explainable.pod') if $ENV{VENUS_RENDER}; 132 | 133 | ok 1 and done_testing; -------------------------------------------------------------------------------- /t/Venus_Role_Mockable.t: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Test::More; 9 | use Venus::Test; 10 | 11 | use Venus 'catch'; 12 | 13 | my $test = test(__FILE__); 14 | 15 | =name 16 | 17 | Venus::Role::Mockable 18 | 19 | =cut 20 | 21 | $test->for('name'); 22 | 23 | =tagline 24 | 25 | Mockable Role 26 | 27 | =cut 28 | 29 | $test->for('tagline'); 30 | 31 | =abstract 32 | 33 | Mockable Role for Perl 5 34 | 35 | =cut 36 | 37 | $test->for('abstract'); 38 | 39 | =includes 40 | 41 | method: mock 42 | 43 | =cut 44 | 45 | $test->for('includes'); 46 | 47 | =synopsis 48 | 49 | package Example; 50 | 51 | use Venus::Class 'with'; 52 | 53 | with 'Venus::Role::Mockable'; 54 | 55 | sub execute { 56 | [1..4]; 57 | } 58 | 59 | package main; 60 | 61 | my $example = Example->new; 62 | 63 | # my $mock = $example->mock(execute => sub { 64 | # my ($next) = @_; 65 | # 66 | # return sub { 67 | # [@{$next->()}, @_] 68 | # } 69 | # }); 70 | 71 | # sub { ... } 72 | 73 | =cut 74 | 75 | $test->for('synopsis', sub { 76 | my ($tryable) = @_; 77 | ok my $result = $tryable->result; 78 | ok $result->isa('Example'); 79 | ok $result->does('Venus::Role::Mockable'); 80 | ok $result->can('mock'); 81 | is_deeply $result->execute, [1..4]; 82 | 83 | $result 84 | }); 85 | 86 | =description 87 | 88 | This package provides a mechanism for mocking subroutines. 89 | 90 | =cut 91 | 92 | $test->for('description'); 93 | 94 | =method mock 95 | 96 | The mock method mocks the subroutine specified using the callback given. The 97 | coderef provided will be passed the original subroutine coderef as its first 98 | argument. The coderef provided should always return a coderef that will serve 99 | as the subroutine mock. 100 | 101 | =signature mock 102 | 103 | mock(string $name, coderef $code) (coderef) 104 | 105 | =metadata mock 106 | 107 | { 108 | since => '2.32', 109 | } 110 | 111 | =example-1 mock 112 | 113 | package main; 114 | 115 | my $example = Example->new; 116 | 117 | my $mock = $example->mock(execute => sub { 118 | my ($next) = @_; 119 | 120 | return sub { 121 | [@{$next->()}, @_] 122 | } 123 | }); 124 | 125 | # sub { ... } 126 | 127 | # $example->execute; 128 | 129 | # [1..4] 130 | 131 | # $example->execute(5, 6); 132 | 133 | # [1..6] 134 | 135 | =cut 136 | 137 | $test->for('example', 1, 'mock', sub { 138 | my ($tryable) = @_; 139 | ok my $result = $tryable->result; 140 | ok ref $result eq 'CODE'; 141 | is_deeply $result->(), [1..4]; 142 | is_deeply $result->(5, 6), [1..6]; 143 | 144 | $result 145 | }); 146 | 147 | =partials 148 | 149 | t/Venus.t: present: authors 150 | t/Venus.t: present: license 151 | 152 | =cut 153 | 154 | $test->for('partials'); 155 | 156 | # END 157 | 158 | $test->render('lib/Venus/Role/Mockable.pod') if $ENV{VENUS_RENDER}; 159 | 160 | ok 1 and done_testing; 161 | -------------------------------------------------------------------------------- /t/Venus_Role_Pluggable.t: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Test::More; 9 | use Venus::Test; 10 | 11 | my $test = test(__FILE__); 12 | 13 | =name 14 | 15 | Venus::Role::Pluggable 16 | 17 | =cut 18 | 19 | $test->for('name'); 20 | 21 | =tagline 22 | 23 | Pluggable Role 24 | 25 | =cut 26 | 27 | $test->for('tagline'); 28 | 29 | =abstract 30 | 31 | Pluggable Role for Perl 5 32 | 33 | =cut 34 | 35 | $test->for('abstract'); 36 | 37 | =synopsis 38 | 39 | package Example::Plugin::Username; 40 | 41 | use Venus::Class; 42 | 43 | use Digest::SHA (); 44 | 45 | sub execute { 46 | my ($self, $example) = @_; 47 | 48 | return Digest::SHA::sha1_hex($example->login); 49 | } 50 | 51 | package Example::Plugin::Password; 52 | 53 | use Venus::Class; 54 | 55 | use Digest::SHA (); 56 | 57 | attr 'value'; 58 | 59 | sub construct { 60 | my ($class, $example) = @_; 61 | 62 | return $class->new(value => $example->secret); 63 | } 64 | 65 | sub execute { 66 | my ($self) = @_; 67 | 68 | return Digest::SHA::sha1_hex($self->value); 69 | } 70 | 71 | package Example; 72 | 73 | use Venus::Class; 74 | 75 | with 'Venus::Role::Proxyable'; 76 | with 'Venus::Role::Pluggable'; 77 | 78 | attr 'login'; 79 | attr 'secret'; 80 | 81 | package main; 82 | 83 | my $example = Example->new(login => 'admin', secret => 'p@ssw0rd'); 84 | 85 | # $example->username; 86 | # $example->password; 87 | 88 | =cut 89 | 90 | $test->for('synopsis', sub { 91 | my ($tryable) = @_; 92 | ok my $result = $tryable->result; 93 | ok $result->isa('Example'); 94 | ok $result->does('Venus::Role::Pluggable'); 95 | is $result->username, 'd033e22ae348aeb5660fc2140aec35850c4da997'; 96 | is $result->password, '57b2ad99044d337197c0c39fd3823568ff81e48a'; 97 | 98 | $result 99 | }); 100 | 101 | =description 102 | 103 | This package provides a mechanism for dispatching to plugin classes. 104 | 105 | =cut 106 | 107 | $test->for('description'); 108 | 109 | =partials 110 | 111 | t/Venus.t: present: authors 112 | t/Venus.t: present: license 113 | 114 | =cut 115 | 116 | $test->for('partials'); 117 | 118 | # END 119 | 120 | $test->render('lib/Venus/Role/Pluggable.pod') if $ENV{VENUS_RENDER}; 121 | 122 | ok 1 and done_testing; -------------------------------------------------------------------------------- /t/Venus_Role_Rejectable.t: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Test::More; 9 | use Venus::Test; 10 | 11 | my $test = test(__FILE__); 12 | 13 | =name 14 | 15 | Venus::Role::Rejectable 16 | 17 | =cut 18 | 19 | $test->for('name'); 20 | 21 | =tagline 22 | 23 | Rejectable Role 24 | 25 | =cut 26 | 27 | $test->for('tagline'); 28 | 29 | =abstract 30 | 31 | Rejectable Role for Perl 5 32 | 33 | =cut 34 | 35 | $test->for('abstract'); 36 | 37 | =synopsis 38 | 39 | package ExampleAccept; 40 | 41 | use Venus::Class 'attr'; 42 | 43 | attr 'name'; 44 | 45 | package ExampleReject; 46 | 47 | use Venus::Class 'attr', 'with'; 48 | 49 | with 'Venus::Role::Rejectable'; 50 | 51 | attr 'name'; 52 | 53 | package main; 54 | 55 | my $example = ExampleReject->new(name => 'example', test => 12345); 56 | 57 | # bless({name => 'example'}, "Example") 58 | 59 | =cut 60 | 61 | $test->for('synopsis', sub { 62 | my ($tryable) = @_; 63 | ok my $result = $tryable->result; 64 | ok $result->isa('ExampleReject'); 65 | ok $result->does('Venus::Role::Rejectable'); 66 | is $result->{name}, 'example'; 67 | ok !exists $result->{test}; 68 | my $example = ExampleAccept->new(name => 'example', test => 12345); 69 | ok $example->isa('ExampleAccept'); 70 | ok !$example->does('Venus::Role::Rejectable'); 71 | is $example->{name}, 'example'; 72 | is $example->{test}, 12345; 73 | 74 | $result 75 | }); 76 | 77 | =description 78 | 79 | This package provides a mechanism for rejecting unexpected constructor arguments. 80 | 81 | =cut 82 | 83 | $test->for('description'); 84 | 85 | =partials 86 | 87 | t/Venus.t: present: authors 88 | t/Venus.t: present: license 89 | 90 | =cut 91 | 92 | $test->for('partials'); 93 | 94 | # END 95 | 96 | $test->render('lib/Venus/Role/Rejectable.pod') if $ENV{VENUS_RENDER}; 97 | 98 | ok 1 and done_testing; 99 | -------------------------------------------------------------------------------- /t/Venus_Role_Stashable.t: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Test::More; 9 | use Venus::Test; 10 | 11 | my $test = test(__FILE__); 12 | 13 | =name 14 | 15 | Venus::Role::Stashable 16 | 17 | =cut 18 | 19 | $test->for('name'); 20 | 21 | =tagline 22 | 23 | Stashable Role 24 | 25 | =cut 26 | 27 | $test->for('tagline'); 28 | 29 | =abstract 30 | 31 | Stashable Role for Perl 5 32 | 33 | =cut 34 | 35 | $test->for('abstract'); 36 | 37 | =includes 38 | 39 | method: stash 40 | 41 | =cut 42 | 43 | $test->for('includes'); 44 | 45 | =synopsis 46 | 47 | package Example; 48 | 49 | use Venus::Class; 50 | 51 | with 'Venus::Role::Stashable'; 52 | 53 | attr 'test'; 54 | 55 | package main; 56 | 57 | my $example = Example->new(test => time); 58 | 59 | # $example->stash; 60 | 61 | =cut 62 | 63 | $test->for('synopsis', sub { 64 | my ($tryable) = @_; 65 | ok my $result = $tryable->result; 66 | ok $result->isa('Example'); 67 | ok $result->does('Venus::Role::Stashable'); 68 | 69 | $result 70 | }); 71 | 72 | =description 73 | 74 | This package modifies the consuming package and provides methods for stashing 75 | data within the object. 76 | 77 | =cut 78 | 79 | $test->for('description'); 80 | 81 | =method stash 82 | 83 | The stash method is used to fetch and stash named values associated with the 84 | object. Calling this method without arguments returns all values. 85 | 86 | =signature stash 87 | 88 | stash(any $key, any $value) (any) 89 | 90 | =metadata stash 91 | 92 | { 93 | since => '0.01', 94 | } 95 | 96 | =example-1 stash 97 | 98 | package main; 99 | 100 | my $example = Example->new(test => time); 101 | 102 | my $stash = $example->stash; 103 | 104 | # {} 105 | 106 | =cut 107 | 108 | $test->for('example', 1, 'stash', sub { 109 | my ($tryable) = @_; 110 | ok my $result = $tryable->result; 111 | is_deeply $result, {}; 112 | 113 | $result 114 | }); 115 | 116 | =example-2 stash 117 | 118 | package main; 119 | 120 | my $example = Example->new(test => time); 121 | 122 | my $stash = $example->stash('test', {1..4}); 123 | 124 | # { 1 => 2, 3 => 4 } 125 | 126 | =cut 127 | 128 | $test->for('example', 2, 'stash', sub { 129 | my ($tryable) = @_; 130 | ok my $result = $tryable->result; 131 | is_deeply $result, { 1 => 2, 3 => 4 }; 132 | 133 | $result 134 | }); 135 | 136 | =example-3 stash 137 | 138 | package main; 139 | 140 | my $example = Example->new(test => time); 141 | 142 | my $stash = $example->stash('test'); 143 | 144 | # undef 145 | 146 | =cut 147 | 148 | $test->for('example', 3, 'stash', sub { 149 | my ($tryable) = @_; 150 | ok !(my $result = $tryable->result); 151 | ok !defined $result; 152 | 153 | !$result 154 | }); 155 | 156 | =partials 157 | 158 | t/Venus.t: present: authors 159 | t/Venus.t: present: license 160 | 161 | =cut 162 | 163 | $test->for('partials'); 164 | 165 | # END 166 | 167 | $test->render('lib/Venus/Role/Stashable.pod') if $ENV{VENUS_RENDER}; 168 | 169 | ok 1 and done_testing; -------------------------------------------------------------------------------- /t/Venus_Role_Superable.t: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Test::More; 9 | use Venus::Test; 10 | 11 | my $test = test(__FILE__); 12 | 13 | =name 14 | 15 | Venus::Role::Superable 16 | 17 | =cut 18 | 19 | $test->for('name'); 20 | 21 | =tagline 22 | 23 | Superable Role 24 | 25 | =cut 26 | 27 | $test->for('tagline'); 28 | 29 | =abstract 30 | 31 | Superable Role for Perl 5 32 | 33 | =cut 34 | 35 | $test->for('abstract'); 36 | 37 | =includes 38 | 39 | method: super 40 | 41 | =cut 42 | 43 | $test->for('includes'); 44 | 45 | =synopsis 46 | 47 | package Example; 48 | 49 | use Venus::Class; 50 | 51 | with 'Venus::Role::Superable'; 52 | 53 | package main; 54 | 55 | my $example = Example->new; 56 | 57 | # $example->super; 58 | 59 | =cut 60 | 61 | $test->for('synopsis', sub { 62 | my ($tryable) = @_; 63 | ok my $result = $tryable->result; 64 | ok $result->isa('Example'); 65 | ok $result->does('Venus::Role::Superable'); 66 | 67 | require Venus::Space; 68 | Venus::Space->new('Example')->unload; 69 | 70 | $result 71 | }); 72 | 73 | =description 74 | 75 | This package modifies the consuming package and provides methods for 76 | dispatching to superclasses using L. 77 | 78 | =cut 79 | 80 | $test->for('description'); 81 | 82 | =method super 83 | 84 | The super method dispatches to superclasses uses the C3 method resolution order 85 | to get better consistency in multiple inheritance situations. 86 | 87 | =signature super 88 | 89 | super(any @args) (any) 90 | 91 | =metadata super 92 | 93 | { 94 | since => '3.55', 95 | } 96 | 97 | =example-1 super 98 | 99 | package Example::A; 100 | 101 | use Venus::Class; 102 | 103 | sub test { 104 | my ($self, @args) = @_; 105 | 106 | return [$self, @args]; 107 | } 108 | 109 | package Example::B; 110 | 111 | use Venus::Class; 112 | 113 | base 'Example::A'; 114 | 115 | with 'Venus::Role::Superable'; 116 | 117 | sub test { 118 | my ($self) = @_; 119 | 120 | return $self->super(1..4); 121 | } 122 | 123 | package main; 124 | 125 | my $example = Example::B->new; 126 | 127 | my $result = $example->test; 128 | 129 | =cut 130 | 131 | $test->for('example', 1, 'super', sub { 132 | my ($tryable) = @_; 133 | ok my $result = $tryable->result; 134 | ok defined $result; 135 | is 0+@{$result}, 5; 136 | is ref $result->[0], 'Example::B'; 137 | is $result->[1], 1; 138 | is $result->[2], 2; 139 | is $result->[3], 3; 140 | is $result->[4], 4; 141 | 142 | require Venus::Space; 143 | Venus::Space->new('Example::A')->unload; 144 | Venus::Space->new('Example::B')->unload; 145 | 146 | $result 147 | }); 148 | 149 | =partials 150 | 151 | t/Venus.t: present: authors 152 | t/Venus.t: present: license 153 | 154 | =cut 155 | 156 | $test->for('partials'); 157 | 158 | # END 159 | 160 | $test->render('lib/Venus/Role/Superable.pod') if $ENV{VENUS_RENDER}; 161 | 162 | ok 1 and done_testing; 163 | -------------------------------------------------------------------------------- /t/Venus_Role_Tryable.t: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Test::More; 9 | use Venus::Test; 10 | 11 | my $test = test(__FILE__); 12 | 13 | =name 14 | 15 | Venus::Role::Tryable 16 | 17 | =cut 18 | 19 | $test->for('name'); 20 | 21 | =tagline 22 | 23 | Tryable Role 24 | 25 | =cut 26 | 27 | $test->for('tagline'); 28 | 29 | =abstract 30 | 31 | Tryable Role for Perl 5 32 | 33 | =cut 34 | 35 | $test->for('abstract'); 36 | 37 | =includes 38 | 39 | method: try 40 | 41 | =cut 42 | 43 | $test->for('includes'); 44 | 45 | =synopsis 46 | 47 | package Example; 48 | 49 | use Venus::Class 'with'; 50 | use Venus 'raise'; 51 | 52 | with 'Venus::Role::Tryable'; 53 | 54 | sub test { 55 | raise 'Example::Error'; 56 | } 57 | 58 | package main; 59 | 60 | my $example = Example->new; 61 | 62 | # $example->try('test'); 63 | 64 | =cut 65 | 66 | $test->for('synopsis', sub { 67 | my ($tryable) = @_; 68 | ok my $result = $tryable->result; 69 | ok $result->isa('Example'); 70 | ok $result->does('Venus::Role::Tryable'); 71 | 72 | $result 73 | }); 74 | 75 | =description 76 | 77 | This package modifies the consuming package and provides a mechanism for 78 | handling potentially volatile routines. 79 | 80 | =cut 81 | 82 | $test->for('description'); 83 | 84 | =method try 85 | 86 | The try method returns a L object having the invocant, callback, 87 | arguments pre-configured. This method supports dispatching, i.e. providing a 88 | method name and arguments whose return value will be acted on by this method. 89 | 90 | =signature try 91 | 92 | try(string | coderef $method, any @args) (Venus::Try) 93 | 94 | =metadata try 95 | 96 | { 97 | since => '0.01', 98 | } 99 | 100 | =example-1 try 101 | 102 | package main; 103 | 104 | my $example = Example->new; 105 | 106 | my $try = $example->try('test'); 107 | 108 | # my $value = $try->result; 109 | 110 | =cut 111 | 112 | $test->for('example', 1, 'try', sub { 113 | my ($tryable) = @_; 114 | ok my $result = $tryable->result; 115 | ok $result->isa('Venus::Try'); 116 | $result->error(\my $error)->result; 117 | ok $error; 118 | ok $error->isa('Example::Error'); 119 | ok $error->isa('Venus::Error'); 120 | 121 | $result 122 | }); 123 | 124 | =partials 125 | 126 | t/Venus.t: present: authors 127 | t/Venus.t: present: license 128 | 129 | =cut 130 | 131 | $test->for('partials'); 132 | 133 | # END 134 | 135 | $test->render('lib/Venus/Role/Tryable.pod') if $ENV{VENUS_RENDER}; 136 | 137 | ok 1 and done_testing; -------------------------------------------------------------------------------- /t/Venus_Role_Unacceptable.t: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Test::More; 9 | use Venus::Test; 10 | 11 | my $test = test(__FILE__); 12 | 13 | =name 14 | 15 | Venus::Role::Unacceptable 16 | 17 | =cut 18 | 19 | $test->for('name'); 20 | 21 | =tagline 22 | 23 | Unacceptable Role 24 | 25 | =cut 26 | 27 | $test->for('tagline'); 28 | 29 | =abstract 30 | 31 | Unacceptable Role for Perl 5 32 | 33 | =cut 34 | 35 | $test->for('abstract'); 36 | 37 | =synopsis 38 | 39 | package ExampleAccept; 40 | 41 | use Venus::Class 'attr'; 42 | 43 | attr 'name'; 44 | 45 | package ExampleDeny; 46 | 47 | use Venus::Class 'attr', 'with'; 48 | 49 | with 'Venus::Role::Unacceptable'; 50 | 51 | attr 'name'; 52 | 53 | package main; 54 | 55 | my $example = ExampleDeny->new(name => 'example', test => 12345); 56 | 57 | # Exception! (isa Venus::Role::Unacceptable::Error) 58 | 59 | =cut 60 | 61 | $test->for('synopsis', sub { 62 | my ($tryable) = @_; 63 | ok my $result = $tryable->error(\my $error)->result; 64 | ok $error->isa('Venus::Role::Unacceptable::Error'); 65 | ok $error->isa('Venus::Error'); 66 | ok $error->is('on.build'); 67 | is_deeply $error->stash('unknowns'), ['test']; 68 | ok $error->message =~ /ExampleDeny was passed unknown attribute/; 69 | my $example = ExampleAccept->new(name => 'example', test => 12345); 70 | ok $example->isa('ExampleAccept'); 71 | ok !$example->does('Venus::Role::Unacceptable'); 72 | is $example->{name}, 'example'; 73 | is $example->{test}, 12345; 74 | 75 | $result 76 | }); 77 | 78 | =description 79 | 80 | This package provides a mechanism for raising an exception when unexpected 81 | constructor arguments are encountered. 82 | 83 | =cut 84 | 85 | $test->for('description'); 86 | 87 | =partials 88 | 89 | t/Venus.t: present: authors 90 | t/Venus.t: present: license 91 | 92 | =cut 93 | 94 | $test->for('partials'); 95 | 96 | # END 97 | 98 | $test->render('lib/Venus/Role/Unacceptable.pod') if $ENV{VENUS_RENDER}; 99 | 100 | ok 1 and done_testing; 101 | -------------------------------------------------------------------------------- /t/Venus_True.t: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | use 5.018; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use Test::More; 9 | use Venus::Test; 10 | 11 | my $test = test(__FILE__); 12 | 13 | =name 14 | 15 | Venus::True 16 | 17 | =cut 18 | 19 | $test->for('name'); 20 | 21 | =tagline 22 | 23 | True Class 24 | 25 | =cut 26 | 27 | $test->for('tagline'); 28 | 29 | =abstract 30 | 31 | True Class for Perl 5 32 | 33 | =cut 34 | 35 | $test->for('abstract'); 36 | 37 | =includes 38 | 39 | method: value 40 | 41 | =cut 42 | 43 | $test->for('includes'); 44 | 45 | =synopsis 46 | 47 | package main; 48 | 49 | use Venus::True; 50 | 51 | my $true = Venus::True->new; 52 | 53 | # $true->value; 54 | 55 | =cut 56 | 57 | $test->for('synopsis', sub { 58 | my ($tryable) = @_; 59 | ok my $result = $tryable->result; 60 | ok $result->isa('Venus::True'); 61 | 62 | $result 63 | }); 64 | 65 | =description 66 | 67 | This package provides the global C value used in L and 68 | the L function. 69 | 70 | =cut 71 | 72 | $test->for('description'); 73 | 74 | =method value 75 | 76 | The value method returns value representing the global C value. 77 | 78 | =signature value 79 | 80 | value() (boolean) 81 | 82 | =metadata value 83 | 84 | { 85 | since => '1.23', 86 | } 87 | 88 | =example-1 value 89 | 90 | # given: synopsis; 91 | 92 | my $value = $true->value; 93 | 94 | # 1 95 | 96 | =cut 97 | 98 | $test->for('example', 1, 'value', sub { 99 | my ($tryable) = @_; 100 | ok my $result = $tryable->result; 101 | 102 | $result 103 | }); 104 | 105 | =partials 106 | 107 | t/Venus.t: present: authors 108 | t/Venus.t: present: license 109 | 110 | =cut 111 | 112 | $test->for('partials'); 113 | 114 | # END 115 | 116 | $test->render('lib/Venus/True.pod') if $ENV{VENUS_RENDER}; 117 | 118 | ok 1 and done_testing; 119 | -------------------------------------------------------------------------------- /t/conf/.vns.pl: -------------------------------------------------------------------------------- 1 | { 2 | data => { 3 | ECHO => 1, 4 | }, 5 | exec => { 6 | brew => 'perlbrew', 7 | cpan => 'cpanm -llocal -qn', 8 | docs => 'perldoc', 9 | each => 'shim -nE', 10 | edit => '$EDITOR $VENUS_FILE', 11 | eval => 'shim -E', 12 | exec => '$PERL', 13 | info => '$PERL -V', 14 | lint => 'perlcritic', 15 | okay => '$PERL -c', 16 | repl => '$REPL', 17 | reup => 'cpanm -qn Venus', 18 | says => 'eval "map log(eval), @ARGV"', 19 | shim => '$PERL -MVenus=true,false,log', 20 | test => '$PROVE', 21 | tidy => 'perltidy', 22 | }, 23 | libs => [ 24 | '-Ilib', 25 | '-Ilocal/lib/perl5', 26 | ], 27 | path => [ 28 | 'bin', 29 | 'dev', 30 | 'local/bin', 31 | ], 32 | perl => { 33 | perl => 'perl', 34 | prove => 'prove', 35 | }, 36 | vars => { 37 | PERL => 'perl', 38 | PROVE => 'prove', 39 | REPL => '$PERL -dE0', 40 | }, 41 | } 42 | -------------------------------------------------------------------------------- /t/conf/asks.perl: -------------------------------------------------------------------------------- 1 | { 2 | asks => { 3 | PASS => 'What\'s the password', 4 | }, 5 | data => { 6 | ECHO => 1 7 | }, 8 | exec => { 9 | brew => "perlbrew", 10 | cpan => "cpanm -llocal -qn", 11 | deps => "cpan --installdeps .", 12 | each => "\$PERL -MVenus=true,false,log -nE", 13 | eval => "\$PERL -MVenus=true,false,log -E", 14 | exec => "\$PERL", 15 | info => "\$PERL -V", 16 | okay => "\$PERL -c", 17 | repl => "\$PERL -dE0", 18 | says => "eval \"map log(\$_), map eval, \@ARGV\"", 19 | test => "\$PROVE" 20 | }, 21 | libs => [ 22 | "-Ilib", 23 | "-Ilocal/lib/perl5" 24 | ], 25 | path => [ 26 | "./bin", 27 | "./dev", 28 | "./local/bin" 29 | ], 30 | perl => { 31 | perl => "perl", 32 | prove => "prove", 33 | }, 34 | vars => { 35 | PERL => "perl", 36 | PROVE => "prove" 37 | }, 38 | } 39 | -------------------------------------------------------------------------------- /t/conf/edit.perl: -------------------------------------------------------------------------------- 1 | { 2 | name => "test" 3 | } 4 | -------------------------------------------------------------------------------- /t/conf/flow.perl: -------------------------------------------------------------------------------- 1 | { 2 | data => { 3 | ECHO => 1 4 | }, 5 | exec => { 6 | brew => "perlbrew", 7 | cpan => "cpanm -llocal -qn", 8 | deps => "cpan --installdeps .", 9 | each => "\$PERL -MVenus=true,false,log -nE", 10 | eval => "\$PERL -MVenus=true,false,log -E", 11 | exec => "\$PERL", 12 | info => "\$PERL -V", 13 | okay => "\$PERL -c", 14 | repl => "\$PERL -dE0", 15 | says => "eval \"map log(\$_), map eval, \@ARGV\"", 16 | test => "\$PROVE" 17 | }, 18 | flow => { 19 | "setup-term" => [ 20 | "cpan Term::ReadKey", 21 | "cpan Term::ReadLine::Gnu", 22 | ], 23 | }, 24 | libs => [ 25 | "-Ilib", 26 | "-Ilocal/lib/perl5" 27 | ], 28 | path => [ 29 | "./bin", 30 | "./dev", 31 | "./local/bin" 32 | ], 33 | perl => { 34 | perl => "perl", 35 | prove => "prove", 36 | }, 37 | vars => { 38 | PERL => "perl", 39 | PROVE => "prove" 40 | }, 41 | } 42 | -------------------------------------------------------------------------------- /t/conf/from.perl: -------------------------------------------------------------------------------- 1 | { 2 | from => [ 3 | "t/conf/.vns.pl", 4 | ], 5 | exec => { 6 | mypan => "cpan -M https://pkg.myapp.com" 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /t/conf/func.perl: -------------------------------------------------------------------------------- 1 | { 2 | data => { 3 | ECHO => 1 4 | }, 5 | exec => { 6 | brew => "perlbrew", 7 | cpan => "cpanm -llocal -qn", 8 | deps => "cpan --installdeps .", 9 | each => "\$PERL -MVenus=true,false,log -nE", 10 | eval => "\$PERL -MVenus=true,false,log -E", 11 | exec => "\$PERL", 12 | info => "\$PERL -V", 13 | okay => "\$PERL -c", 14 | repl => "\$PERL -dE0", 15 | says => "eval \"map log(\$_), map eval, \@ARGV\"", 16 | test => "\$PROVE" 17 | }, 18 | func => { 19 | "dump" => "./t/path/etc/dump.pl", 20 | }, 21 | libs => [ 22 | "-Ilib", 23 | "-Ilocal/lib/perl5" 24 | ], 25 | path => [ 26 | "./bin", 27 | "./dev", 28 | "./local/bin" 29 | ], 30 | perl => { 31 | perl => "perl", 32 | prove => "prove", 33 | }, 34 | vars => { 35 | PERL => "perl", 36 | PROVE => "prove" 37 | }, 38 | } 39 | -------------------------------------------------------------------------------- /t/conf/help.perl: -------------------------------------------------------------------------------- 1 | { 2 | data => { 3 | ECHO => 1, 4 | }, 5 | exec => { 6 | exec => "perl -c", 7 | }, 8 | help => { 9 | exec => "Usage: perl -c ", 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /t/conf/psql.perl: -------------------------------------------------------------------------------- 1 | { 2 | data => { 3 | ECHO => 1, 4 | }, 5 | exec => { 6 | backup => "pg_backupcluster", 7 | restore => "pg_restorecluster", 8 | }, 9 | } 10 | -------------------------------------------------------------------------------- /t/conf/read.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Test", 3 | "$metadata": { 4 | "varlog": "/var/log", 5 | "tmplog": "/tmp/log" 6 | }, 7 | "$services": { 8 | "log": { 9 | "package": "Venus/Path", 10 | "argument": { 11 | "$metadata": "tmplog" 12 | } 13 | }, 14 | "development_log": { 15 | "package": "Venus/Path", 16 | "extends": "log", 17 | "builder": [ 18 | { 19 | "method": "new", 20 | "return": "self", 21 | "inject": "list" 22 | }, 23 | { 24 | "method": "child", 25 | "argument": "development.log", 26 | "return": "result" 27 | } 28 | ] 29 | }, 30 | "production_log": { 31 | "package": "Venus/Path", 32 | "extends": "log", 33 | "argument": { 34 | "$metadata": "varlog" 35 | }, 36 | "builder": [ 37 | { 38 | "method": "new", 39 | "return": "self", 40 | "inject": "hash" 41 | }, 42 | { 43 | "method": "child", 44 | "argument": "production.log", 45 | "return": "result" 46 | } 47 | ] 48 | }, 49 | "staging_log": { 50 | "package": "Venus/Path", 51 | "extends": "log", 52 | "builder": [ 53 | { 54 | "method": "new", 55 | "return": "self", 56 | "inject": "hash" 57 | }, 58 | { 59 | "method": "child", 60 | "argument": "staging.log", 61 | "return": "result" 62 | } 63 | ] 64 | }, 65 | "testing_log": { 66 | "package": "Venus::Path", 67 | "builder": [ 68 | { 69 | "method": "new", 70 | "argument": { 71 | "$service": "filetemp" 72 | }, 73 | "return": "self" 74 | }, 75 | { 76 | "method": "child", 77 | "argument": "testing.log", 78 | "return": "result" 79 | } 80 | ] 81 | }, 82 | "filetemp": { 83 | "package": "File/Temp", 84 | "constructor": "newdir" 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /t/conf/read.perl: -------------------------------------------------------------------------------- 1 | { 2 | 'name' => 'Test', 3 | '$metadata' => { 4 | 'varlog' => '/var/log', 5 | 'tmplog' => '/tmp/log', 6 | }, 7 | '$services' => { 8 | 'log' => { 9 | 'package' => 'Venus/Path', 10 | 'argument' => { 11 | '$metadata' => 'tmplog' 12 | } 13 | }, 14 | 'development_log' => { 15 | 'package' => 'Venus/Path', 16 | 'extends' => 'log', 17 | 'builder' => [ 18 | { 19 | 'method' => 'new', 20 | 'return' => 'self', 21 | 'inject' => 'list' 22 | }, 23 | { 24 | 'method' => 'child', 25 | 'argument' => 'development.log', 26 | 'return' => 'result' 27 | }, 28 | ] 29 | }, 30 | 'production_log' => { 31 | 'package' => 'Venus/Path', 32 | 'extends' => 'log', 33 | 'argument' => { 34 | '$metadata' => 'varlog' 35 | }, 36 | 'builder' => [ 37 | { 38 | 'method' => 'new', 39 | 'return' => 'self', 40 | 'inject' => 'hash' 41 | }, 42 | { 43 | 'method' => 'child', 44 | 'argument' => 'production.log', 45 | 'return' => 'result' 46 | }, 47 | ] 48 | }, 49 | 'staging_log' => { 50 | 'package' => 'Venus/Path', 51 | 'extends' => 'log', 52 | 'builder' => [ 53 | { 54 | 'method' => 'new', 55 | 'return' => 'self', 56 | 'inject' => 'hash' 57 | }, 58 | { 59 | 'method' => 'child', 60 | 'argument' => 'staging.log', 61 | 'return' => 'result' 62 | }, 63 | ] 64 | }, 65 | 'testing_log' => { 66 | 'package' => 'Venus::Path', 67 | 'builder' => [ 68 | { 69 | 'method' => 'new', 70 | 'argument' => { 71 | '$service' => 'filetemp', 72 | }, 73 | 'return' => 'self', 74 | }, 75 | { 76 | 'method' => 'child', 77 | 'argument' => 'testing.log', 78 | 'return' => 'result' 79 | }, 80 | ] 81 | }, 82 | 'filetemp' => { 83 | 'package' => 'File/Temp', 84 | 'constructor' => 'newdir', 85 | }, 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /t/conf/read.yaml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | $metadata: 4 | varlog: /var/log 5 | tmplog: /tmp/log 6 | 7 | $services: 8 | log: 9 | package: Venus/Path 10 | argument: 11 | $metadata: tmplog 12 | development_log: 13 | package: Venus/Path 14 | extends: log 15 | builder: 16 | - method: new 17 | return: self 18 | inject: list 19 | - method: child 20 | argument: development.log 21 | return: result 22 | production_log: 23 | package: Venus/Path 24 | extends: log 25 | argument: 26 | $metadata: varlog 27 | builder: 28 | - method: new 29 | return: self 30 | inject: hash 31 | - method: child 32 | argument: production.log 33 | return: result 34 | staging_log: 35 | package: Venus/Path 36 | extends: log 37 | builder: 38 | - method: new 39 | return: self 40 | inject: hash 41 | - method: child 42 | argument: staging.log 43 | return: result 44 | testing_log: 45 | package: Venus::Path 46 | builder: 47 | - method: new 48 | argument: 49 | $service: filetemp 50 | return: self 51 | - method: child 52 | argument: testing.log 53 | return: result 54 | filetemp: 55 | package: File/Temp 56 | constructor: newdir 57 | -------------------------------------------------------------------------------- /t/conf/when.perl: -------------------------------------------------------------------------------- 1 | { 2 | data => { 3 | ECHO => 1, 4 | }, 5 | exec => { 6 | name => "echo \$OSNAME" 7 | }, 8 | when => { 9 | is_lin => { 10 | data => { 11 | OSNAME => "LINUX", 12 | }, 13 | }, 14 | is_win => { 15 | data => { 16 | OSNAME => "WINDOWS", 17 | }, 18 | }, 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /t/conf/with.perl: -------------------------------------------------------------------------------- 1 | { 2 | data => { 3 | ECHO => 1 4 | }, 5 | exec => { 6 | brew => "perlbrew", 7 | cpan => "cpanm -llocal -qn", 8 | deps => "cpan --installdeps .", 9 | each => "\$PERL -MVenus=true,false,log -nE", 10 | eval => "\$PERL -MVenus=true,false,log -E", 11 | exec => "\$PERL", 12 | info => "\$PERL -V", 13 | okay => "\$PERL -c", 14 | repl => "\$PERL -dE0", 15 | says => "eval \"map log(\$_), map eval, \@ARGV\"", 16 | test => "\$PROVE" 17 | }, 18 | find => {}, 19 | libs => [ 20 | "-Ilib", 21 | "-Ilocal/lib/perl5" 22 | ], 23 | load => [], 24 | path => [ 25 | "./bin", 26 | "./dev", 27 | "./local/bin" 28 | ], 29 | perl => { 30 | perl => "perl", 31 | "perl-5.18.0" => "perlbrew exec --with perl-5.18.0 perl", 32 | prove => "prove", 33 | "prove-5.18.0" => "perlbrew exec --with perl-5.18.0 prove" 34 | }, 35 | task => {}, 36 | vars => { 37 | PERL => "perl", 38 | PROVE => "prove" 39 | }, 40 | with => { 41 | psql => "t/conf/psql.perl", 42 | }, 43 | } 44 | -------------------------------------------------------------------------------- /t/conf/write.json: -------------------------------------------------------------------------------- 1 | { 2 | "$services" : { 3 | "log" : { 4 | "argument" : { 5 | "value" : "." 6 | }, 7 | "package" : "Venus\/Path" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /t/conf/write.perl: -------------------------------------------------------------------------------- 1 | { 2 | "\$services" => { 3 | log => { 4 | argument => { 5 | value => "." 6 | }, 7 | package => "Venus/Path" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /t/conf/write.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | $services: 3 | log: 4 | argument: 5 | value: . 6 | package: Venus/Path 7 | -------------------------------------------------------------------------------- /t/data/moon: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awncorp/venus/a0c216126c87116a3a5c913e06faffdaa5599c91/t/data/moon -------------------------------------------------------------------------------- /t/data/planets/ceres: -------------------------------------------------------------------------------- 1 | ceres -------------------------------------------------------------------------------- /t/data/planets/earth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awncorp/venus/a0c216126c87116a3a5c913e06faffdaa5599c91/t/data/planets/earth -------------------------------------------------------------------------------- /t/data/planets/eris: -------------------------------------------------------------------------------- 1 | eris -------------------------------------------------------------------------------- /t/data/planets/haumea: -------------------------------------------------------------------------------- 1 | haumea -------------------------------------------------------------------------------- /t/data/planets/jupiter: -------------------------------------------------------------------------------- 1 | jupiter -------------------------------------------------------------------------------- /t/data/planets/makemake: -------------------------------------------------------------------------------- 1 | makemake -------------------------------------------------------------------------------- /t/data/planets/mars: -------------------------------------------------------------------------------- 1 | mars -------------------------------------------------------------------------------- /t/data/planets/mercury: -------------------------------------------------------------------------------- 1 | mercury -------------------------------------------------------------------------------- /t/data/planets/neptune: -------------------------------------------------------------------------------- 1 | neptune -------------------------------------------------------------------------------- /t/data/planets/planet9: -------------------------------------------------------------------------------- 1 | planet 2 | nine -------------------------------------------------------------------------------- /t/data/planets/pluto: -------------------------------------------------------------------------------- 1 | pluto -------------------------------------------------------------------------------- /t/data/planets/saturn: -------------------------------------------------------------------------------- 1 | saturn -------------------------------------------------------------------------------- /t/data/planets/uranus: -------------------------------------------------------------------------------- 1 | uranus -------------------------------------------------------------------------------- /t/data/planets/venus: -------------------------------------------------------------------------------- 1 | venus -------------------------------------------------------------------------------- /t/data/sections: -------------------------------------------------------------------------------- 1 | # pod syntax 2 | 3 | =head1 NAME 4 | 5 | Example #1 6 | 7 | =cut 8 | 9 | =head1 NAME 10 | 11 | Example #2 12 | 13 | =cut 14 | 15 | =head1 ABSTRACT 16 | 17 | Example Abstract 18 | 19 | =cut 20 | 21 | # pod-ish syntax 22 | 23 | =name 24 | 25 | Example #1 26 | 27 | =cut 28 | 29 | =name 30 | 31 | Example #2 32 | 33 | =cut 34 | 35 | __DATA__ 36 | 37 | # data syntax 38 | 39 | @@ name 40 | 41 | Example Name 42 | 43 | @@ end 44 | 45 | @@ titles #1 46 | 47 | Example Title #1 48 | 49 | @@ end 50 | 51 | @@ titles #2 52 | 53 | Example Title #2 54 | 55 | @@ end -------------------------------------------------------------------------------- /t/data/sun: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | exit(1); 4 | -------------------------------------------------------------------------------- /t/path/001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awncorp/venus/a0c216126c87116a3a5c913e06faffdaa5599c91/t/path/001 -------------------------------------------------------------------------------- /t/path/etc/dump.pl: -------------------------------------------------------------------------------- 1 | sub {[@_]} 2 | -------------------------------------------------------------------------------- /t/path/user/bin/app3: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | exit(0); 4 | -------------------------------------------------------------------------------- /t/path/user/bin/app3.exe: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | exit(0); 4 | -------------------------------------------------------------------------------- /t/path/user/bin/cmd: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | exit(0); 4 | -------------------------------------------------------------------------------- /t/path/user/local/bin/app1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | exit(0); 4 | -------------------------------------------------------------------------------- /t/path/user/local/bin/app2: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | exit(0); 4 | -------------------------------------------------------------------------------- /t/path/user/local/bin/app4: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | exit(0); 4 | -------------------------------------------------------------------------------- /t/path/user/local/bin/cmd: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | exit(0); 4 | -------------------------------------------------------------------------------- /t/path/usr/bin/app1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | exit(0); 4 | -------------------------------------------------------------------------------- /t/path/usr/bin/app2: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | exit(0); 4 | -------------------------------------------------------------------------------- /t/path/usr/bin/cmd: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | exit(0); 4 | -------------------------------------------------------------------------------- /t/path/usr/local/bin/app4: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | exit(0); 4 | -------------------------------------------------------------------------------- /t/path/usr/local/bin/cmd: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | exit(0); 4 | -------------------------------------------------------------------------------- /t/path/usr/local/sbin/app4: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | exit(0); 4 | -------------------------------------------------------------------------------- /t/path/usr/local/sbin/cmd: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | exit(0); 4 | -------------------------------------------------------------------------------- /t/path/usr/sbin/app1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | exit(0); 4 | -------------------------------------------------------------------------------- /t/path/usr/sbin/app3: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | exit(0); 4 | -------------------------------------------------------------------------------- /t/path/usr/sbin/cmd: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | exit(0); 4 | -------------------------------------------------------------------------------- /wiki/_footer.md: -------------------------------------------------------------------------------- 1 | **Venus - OO Standard Library for Perl 5** 2 | 3 | * [Tarball](https://github.com/awncorp/venus/archive/refs/heads/master.tar.gz) 4 | * [Discussions](https://github.com/awncorp/venus/discussions) 5 | * [Issues](https://github.com/awncorp/venus/issues) 6 | * [Releases](https://github.com/awncorp/venus/tags) 7 | * [CPAN](https://metacpan.org/dist/Venus) -------------------------------------------------------------------------------- /wiki/_sidebar.md: -------------------------------------------------------------------------------- 1 | **Info** 2 | 3 | - [Home](home) 4 | 5 | **Content** 6 | 7 | - [Preamble](preamble) 8 | - [Backstory](backstory) 9 | 10 | **Packages** 11 | 12 | - [Roles](roles) 13 | - [System](system) 14 | - [Utilities](utilities) 15 | - [Values](values) 16 | -------------------------------------------------------------------------------- /wiki/home.md: -------------------------------------------------------------------------------- 1 | # NAME 2 | 3 | Venus 4 | 5 | # ABSTRACT 6 | 7 | OO Standard Library for Perl 5 8 | 9 | # DESCRIPTION 10 | 11 | Venus is an object-orientation framework and extendible standard library for 12 | Perl 5, built on top of Mars architecture with classes which wrap most native 13 | [Perl](https://www.perl.org/) data types. Venus has a simple modular 14 | architecture, robust library of classes and methods, supports pure-Perl 15 | autoboxing, advanced exception handling, "true" and "false" keywords, package 16 | introspection, command-line options parsing, and more. 17 | 18 | # RESOURCES 19 | 20 | - [Info](info) - Background 21 | - [Values](values) - Value classes 22 | - [Utilities](utilities) - Utilities classes 23 | - [Roles/Traits](roles) - Abstract behaviors 24 | - [System](system) - Framework and object-system 25 | 26 | # INSTALLATION 27 | 28 | Install Venus using [cpm](https://metacpan.org/pod/App::cpm): 29 | 30 | ```bash 31 | cpm install Venus 32 | ``` 33 | 34 | Install Venus using [cpanm](https://metacpan.org/pod/App::cpanminus): 35 | 36 | ```bash 37 | cpanm -qn Venus 38 | ``` 39 | 40 | Install Venus using Perl: 41 | 42 | ```bash 43 | curl -sSL https://cpanmin.us | perl - -qn Venus 44 | ``` 45 | 46 | Install Venus using Perl (from GitHub): 47 | 48 | ```bash 49 | curl -ssL https://cpanmin.us | perl - -qn git://github.com/awncorp/venus.git 50 | ``` 51 | 52 | # QUOTE 53 | 54 | "Most software today is very much like an Egyptian pyramid with millions of 55 | bricks piled on top of each other, with no structural integrity, but just done 56 | by brute force and thousands of slaves." -- Alan Kay 57 | 58 | # AUTHORS 59 | 60 | Awncorp, `awncorp@cpan.org` 61 | -------------------------------------------------------------------------------- /wiki/info.md: -------------------------------------------------------------------------------- 1 | # NAME 2 | 3 | Venus - Info 4 | 5 | # ABSTRACT 6 | 7 | Background Information 8 | 9 | # RESOURCES 10 | 11 | - [Preamble](preamble) - High-level intro 12 | - [Backstory](backstory) - Background info 13 | 14 | # INSTALLATION 15 | 16 | Install Venus using [cpm](https://metacpan.org/pod/App::cpm): 17 | 18 | ```bash 19 | cpm install Venus 20 | ``` 21 | 22 | Install Venus using [cpanm](https://metacpan.org/pod/App::cpanminus): 23 | 24 | ```bash 25 | cpanm -qn Venus 26 | ``` 27 | 28 | Install Venus using Perl: 29 | 30 | ```bash 31 | curl -sSL https://cpanmin.us | perl - -qn Venus 32 | ``` 33 | 34 | Install Venus using Perl (from GitHub): 35 | 36 | ```bash 37 | curl -ssL https://cpanmin.us | perl - -qn git://github.com/awncorp/venus.git 38 | ``` 39 | -------------------------------------------------------------------------------- /wiki/roles.md: -------------------------------------------------------------------------------- 1 | # NAME 2 | 3 | Venus - Roles 4 | 5 | # ABSTRACT 6 | 7 | Standard Library Abstract Behaviors 8 | 9 | # RESOURCES 10 | 11 | **Roles** 12 | 13 | _The roles are packages that can be applied to any Venus-based class, which provide sets of methods for performing specific operations._ 14 | 15 | - [Venus::Role::Accessible](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Accessible.pod) 16 | - [Venus::Role::Assertable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Assertable.pod) 17 | - [Venus::Role::Boxable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Boxable.pod) 18 | - [Venus::Role::Buildable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Buildable.pod) 19 | - [Venus::Role::Catchable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Catchable.pod) 20 | - [Venus::Role::Coercible](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Coercible.pod) 21 | - [Venus::Role::Comparable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Comparable.pod) 22 | - [Venus::Role::Defaultable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Defaultable.pod) 23 | - [Venus::Role::Digestable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Digestable.pod) 24 | - [Venus::Role::Doable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Doable.pod) 25 | - [Venus::Role::Dumpable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Dumpable.pod) 26 | - [Venus::Role::Explainable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Explainable.pod) 27 | - [Venus::Role::Makeable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Makeable.pod) 28 | - [Venus::Role::Mappable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Mappable.pod) 29 | - [Venus::Role::Matchable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Matchable.pod) 30 | - [Venus::Role::Pluggable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Pluggable.pod) 31 | - [Venus::Role::Printable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Printable.pod) 32 | - [Venus::Role::Proxyable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Proxyable.pod) 33 | - [Venus::Role::Reflectable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Reflectable.pod) 34 | - [Venus::Role::Rejectable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Rejectable.pod) 35 | - [Venus::Role::Stashable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Stashable.pod) 36 | - [Venus::Role::Testable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Testable.pod) 37 | - [Venus::Role::Throwable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Throwable.pod) 38 | - [Venus::Role::Tryable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Tryable.pod) 39 | - [Venus::Role::Unacceptable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Unacceptable.pod) 40 | - [Venus::Role::Valuable](https://github.com/awncorp/venus/blob/master/lib/Venus/Role/Valuable.pod) -------------------------------------------------------------------------------- /wiki/system.md: -------------------------------------------------------------------------------- 1 | # NAME 2 | 3 | Venus - System 4 | 5 | # ABSTRACT 6 | 7 | Framework and Object System Packages 8 | 9 | # RESOURCES 10 | 11 | **Shims** 12 | 13 | _The shims are packages intended to be used directly._ 14 | 15 | - [Venus::Class](https://github.com/awncorp/venus/blob/master/lib/Venus/Class.pod) - Class Builder 16 | - [Venus::Mixin](https://github.com/awncorp/venus/blob/master/lib/Venus/Mixin.pod) - Mixin Builder 17 | - [Venus::Role](https://github.com/awncorp/venus/blob/master/lib/Venus/Role.pod) - Role Builder 18 | 19 | **Bases** 20 | 21 | _The bases are packages used by shims that consumers derive from._ 22 | 23 | - [Venus::Core](https://github.com/awncorp/venus/blob/master/lib/Venus/Core.pod) - Core Base Class 24 | - [Venus::Core::Class](https://github.com/awncorp/venus/blob/master/lib/Venus/Core/Class.pod) - Class Base Class 25 | - [Venus::Core::Mixin](https://github.com/awncorp/venus/blob/master/lib/Venus/Core/Mixin.pod) - Mixin Base Class 26 | - [Venus::Core::Role](https://github.com/awncorp/venus/blob/master/lib/Venus/Core/Role.pod) - Role Base Class 27 | 28 | **Kinds** 29 | 30 | _The kinds are base classes used by all other Venus classes._ 31 | 32 | - [Venus::Kind](https://github.com/awncorp/venus/blob/master/lib/Venus/Kind.pod) - Kind Base Class 33 | - [Venus::Kind::Utility](https://github.com/awncorp/venus/blob/master/lib/Venus/Kind/Utility.pod) - Utility Base Class 34 | - [Venus::Kind::Value](https://github.com/awncorp/venus/blob/master/lib/Venus/Kind/Value.pod) - Value Base Class 35 | 36 | **Tools** 37 | 38 | _The tools are classes that support automating aspects of the framework._ 39 | 40 | - [Venus::Meta](https://github.com/awncorp/venus/blob/master/lib/Venus/Meta.pod) - Class Metadata 41 | -------------------------------------------------------------------------------- /wiki/utilities.md: -------------------------------------------------------------------------------- 1 | # NAME 2 | 3 | Venus - Utilities 4 | 5 | # ABSTRACT 6 | 7 | Standard Library Utility Classes 8 | 9 | # RESOURCES 10 | 11 | **Utilities** 12 | 13 | _The utilities are packages which provide methods for performing common computing tasks._ 14 | 15 | - [Venus::Args](https://github.com/awncorp/venus/blob/master/lib/Venus/Args.pod) - Args Class 16 | - [Venus::Assert](https://github.com/awncorp/venus/blob/master/lib/Venus/Assert.pod) - Assert Class 17 | - [Venus::Box](https://github.com/awncorp/venus/blob/master/lib/Venus/Box.pod) - Box Class 18 | - [Venus::Data](https://github.com/awncorp/venus/blob/master/lib/Venus/Data.pod) - Data Class 19 | - [Venus::Date](https://github.com/awncorp/venus/blob/master/lib/Venus/Date.pod) - Date Class 20 | - [Venus::Error](https://github.com/awncorp/venus/blob/master/lib/Venus/Error.pod) - Error Class 21 | - [Venus::False](https://github.com/awncorp/venus/blob/master/lib/Venus/False.pod) - False Class 22 | - [Venus::Json](https://github.com/awncorp/venus/blob/master/lib/Venus/Json.pod) - Json Class 23 | - [Venus::Match](https://github.com/awncorp/venus/blob/master/lib/Venus/Match.pod) - Match Class 24 | - [Venus::Name](https://github.com/awncorp/venus/blob/master/lib/Venus/Name.pod) - Name Class 25 | - [Venus::Opts](https://github.com/awncorp/venus/blob/master/lib/Venus/Opts.pod) - Opts Class 26 | - [Venus::Path](https://github.com/awncorp/venus/blob/master/lib/Venus/Path.pod) - Path Class 27 | - [Venus::Process](https://github.com/awncorp/venus/blob/master/lib/Venus/Process.pod) - Process Class 28 | - [Venus::Random](https://github.com/awncorp/venus/blob/master/lib/Venus/Random.pod) - Random Class 29 | - [Venus::Replace](https://github.com/awncorp/venus/blob/master/lib/Venus/Replace.pod) - Replace Class 30 | - [Venus::Search](https://github.com/awncorp/venus/blob/master/lib/Venus/Search.pod) - Search Class 31 | - [Venus::Space](https://github.com/awncorp/venus/blob/master/lib/Venus/Space.pod) - Space Class 32 | - [Venus::Template](https://github.com/awncorp/venus/blob/master/lib/Venus/Template.pod) - Template Class 33 | - [Venus::Test](https://github.com/awncorp/venus/blob/master/lib/Venus/Test.pod) - Test Class 34 | - [Venus::Throw](https://github.com/awncorp/venus/blob/master/lib/Venus/Throw.pod) - Throw Class 35 | - [Venus::True](https://github.com/awncorp/venus/blob/master/lib/Venus/True.pod) - True Class 36 | - [Venus::Try](https://github.com/awncorp/venus/blob/master/lib/Venus/Try.pod) - Try Class 37 | - [Venus::Type](https://github.com/awncorp/venus/blob/master/lib/Venus/Type.pod) - Type Class 38 | - [Venus::Vars](https://github.com/awncorp/venus/blob/master/lib/Venus/Vars.pod) - Vars Class 39 | - [Venus::Yaml](https://github.com/awncorp/venus/blob/master/lib/Venus/Yaml.pod) - Yaml Class -------------------------------------------------------------------------------- /wiki/values.md: -------------------------------------------------------------------------------- 1 | # NAME 2 | 3 | Venus - Values 4 | 5 | # ABSTRACT 6 | 7 | Standard Library Value Classes 8 | 9 | # RESOURCES 10 | 11 | **Values** 12 | 13 | _The values are packages which provide methods for performing common operations on native Perl data types._ 14 | 15 | - [Venus::Array](https://github.com/awncorp/venus/blob/master/lib/Venus/Array.pod) - Array Class 16 | - [Venus::Boolean](https://github.com/awncorp/venus/blob/master/lib/Venus/Boolean.pod) - Boolean Class 17 | - [Venus::Code](https://github.com/awncorp/venus/blob/master/lib/Venus/Code.pod) - Code Class 18 | - [Venus::Float](https://github.com/awncorp/venus/blob/master/lib/Venus/Float.pod) - Float Class 19 | - [Venus::Hash](https://github.com/awncorp/venus/blob/master/lib/Venus/Hash.pod) - Hash Class 20 | - [Venus::Number](https://github.com/awncorp/venus/blob/master/lib/Venus/Number.pod) - Number Class 21 | - [Venus::Regexp](https://github.com/awncorp/venus/blob/master/lib/Venus/Regexp.pod) - Regexp Class 22 | - [Venus::Scalar](https://github.com/awncorp/venus/blob/master/lib/Venus/Scalar.pod) - Scalar Class 23 | - [Venus::String](https://github.com/awncorp/venus/blob/master/lib/Venus/String.pod) - String Class 24 | - [Venus::Undef](https://github.com/awncorp/venus/blob/master/lib/Venus/Undef.pod) - Undef Class --------------------------------------------------------------------------------