Projects
Mega:23.09
rubygem-docile
Sign Up
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 3
View file
_service:tar_scm:rubygem-docile.spec
Changed
@@ -1,7 +1,7 @@ %global gem_name docile Summary: Docile keeps your Ruby DSLs tame and well-behaved Name: rubygem-%{gem_name} -Version: 1.1.5 +Version: 1.4.0 Release: 1 License: MIT URL: https://ms-ati.github.com/docile/ @@ -52,10 +52,14 @@ %doc %{gem_docdir} %doc %{gem_instdir}/HISTORY.md %doc %{gem_instdir}/README.md -%{gem_instdir}/on_what.rb %{gem_instdir}/Rakefile -%{gem_instdir}/spec +%exclude %{_datadir}/gems/gems/%{gem_name}-%{version}/.github/* +%exclude %{_datadir}/gems/gems/%{gem_name}-%{version}/.rubocop.yml +%exclude %{_datadir}/gems/gems/%{gem_name}-%{version}/SECURITY.md %changelog +* Mon Nov 13 2023 Ge Wang <wang__Ge@126.com> - 1.4.0-1 +- update to version 1.4.0 + * Sat Aug 22 2020 liyanan <liyanan32@huawei.com> - 1.1.5-1 - package init
View file
_service
Changed
@@ -2,7 +2,7 @@ <service name="tar_scm"> <param name="url">git@gitee.com:src-openeuler/rubygem-docile.git</param> <param name="scm">git</param> - <param name="revision">openEuler-23.09</param> + <param name="revision">master</param> <param name="exclude">*</param> <param name="extract">*</param> </service>
View file
_service:tar_scm:docile-1.1.5.gem/data/.ruby-gemset
Deleted
@@ -1,1 +0,0 @@ -docile
View file
_service:tar_scm:docile-1.1.5.gem/data/.ruby-version
Deleted
@@ -1,1 +0,0 @@ -ruby-2.1.0
View file
_service:tar_scm:docile-1.1.5.gem/data/.travis.yml
Deleted
@@ -1,21 +0,0 @@ -language: ruby -cache: bundler -rvm: - - ruby-head - - 2.1.2 - - 2.1.1 - - 2.1.0 - - 2.0.0 - - 1.9.3 - - 1.9.2 - - 1.8.7 - - ree - - jruby-head - - jruby-19mode - - jruby-18mode - - rbx-2 -matrix: - allow_failures: - - rvm: ruby-head - - rvm: jruby-head - fast_finish: true
View file
_service:tar_scm:docile-1.1.5.gem/data/on_what.rb
Deleted
@@ -1,14 +0,0 @@ -# NOTE: Very simple tests for what system we are on, extracted for sharing -# between Rakefile, gemspec, and spec_helper. Not for use in actual library. - -def on_travis? - ENV'CI' == 'true' -end - -def on_jruby? - (defined?(RUBY_ENGINE) && 'jruby' == RUBY_ENGINE) -end - -def on_1_8? - RUBY_VERSION.start_with? '1.8' -end \ No newline at end of file
View file
_service:tar_scm:docile-1.1.5.gem/data/spec/docile_spec.rb
Deleted
@@ -1,339 +0,0 @@ -require 'spec_helper' -require 'singleton' - -describe Docile do - - describe '.dsl_eval' do - - context 'when DSL context object is an Array' do - let(:array) { } - let!(:result) { execute_dsl_against_array } - - def execute_dsl_against_array - Docile.dsl_eval(array) do - push 1 - push 2 - pop - push 3 - end - end - - it 'executes the block against the DSL context object' do - expect(array).to eq(1, 3) - end - - it 'returns the DSL object after executing block against it' do - expect(result).to eq(array) - end - - it "doesn't proxy #__id__" do - Docile.dsl_eval(array) { expect(__id__).not_to eq(array.__id__) } - end - - it "raises NoMethodError if the DSL object doesn't implement the method" do - expect { Docile.dsl_eval(array) { no_such_method } }.to raise_error(NoMethodError) - end - end - - Pizza = Struct.new(:cheese, :pepperoni, :bacon, :sauce) - - class PizzaBuilder - def cheese(v=true); @cheese = v; end - def pepperoni(v=true); @pepperoni = v; end - def bacon(v=true); @bacon = v; end - def sauce(v=nil); @sauce = v; end - def build - Pizza.new(!!@cheese, !!@pepperoni, !!@bacon, @sauce) - end - end - - context 'when DSL context object is a Builder pattern' do - let(:builder) { PizzaBuilder.new } - let(:result) { execute_dsl_against_builder_and_call_build } - - def execute_dsl_against_builder_and_call_build - @sauce = :extra - Docile.dsl_eval(builder) do - bacon - cheese - sauce @sauce - end.build - end - - it 'returns correctly built object' do - expect(result).to eq(Pizza.new(true, false, true, :extra)) - end - end - - class InnerDSL - def initialize; @b = 'b'; end - attr_accessor :b - end - - class OuterDSL - def initialize; @a = 'a'; end - attr_accessor :a - - def inner(&block) - Docile.dsl_eval(InnerDSL.new, &block) - end - - def inner_with_params(param, &block) - Docile.dsl_eval(InnerDSL.new, param, :foo, &block) - end - end - - def outer(&block) - Docile.dsl_eval(OuterDSL.new, &block) - end - - context 'when given parameters for the DSL block' do - def parameterized(*args, &block) - Docile.dsl_eval(OuterDSL.new, *args, &block) - end - - it 'passes parameters to the block' do - parameterized(1,2,3) do |x,y,z| - expect(x).to eq(1) - expect(y).to eq(2) - expect(z).to eq(3) - end - end - - it 'finds parameters before methods' do - parameterized(1) { |a| expect(a).to eq(1) } - end - - it 'find outer dsl parameters in inner dsl scope' do - parameterized(1,2,3) do |a,b,c| - inner_with_params(c) do |d,e| - expect(a).to eq(1) - expect(b).to eq(2) - expect(c).to eq(3) - expect(d).to eq(c) - expect(e).to eq(:foo) - end - end - end - end - - class DSLWithNoMethod - def initialize(b); @b = b; end - attr_accessor :b - def push_element - @b.push 1 - end - end - - context 'when DSL have NoMethod error inside' do - it 'raise error from nil' do - Docile.dsl_eval(DSLWithNoMethod.new(nil)) do - expect { push_element }.to raise_error(NoMethodError, /undefined method `push' (for|on) nil:NilClass/) - end - end - end - - context 'when DSL blocks are nested' do - - context 'method lookup' do - it 'finds method of outer dsl in outer dsl scope' do - outer { expect(a).to eq('a') } - end - - it 'finds method of inner dsl in inner dsl scope' do - outer { inner { expect(b).to eq('b') } } - end - - it 'finds method of outer dsl in inner dsl scope' do - outer { inner { expect(a).to eq('a') } } - end - - it "finds method of block's context in outer dsl scope" do - def c; 'c'; end - outer { expect(c).to eq('c') } - end - - it "finds method of block's context in inner dsl scope" do - def c; 'c'; end - outer { inner { expect(c).to eq('c') } } - end - - it 'finds method of outer dsl in preference to block context' do - def a; 'not a'; end - outer { expect(a).to eq('a') } - outer { inner { expect(a).to eq('a') } } - end - end - - context 'local variable lookup' do - it 'finds local variable from block context in outer dsl scope' do - foo = 'foo' - outer { expect(foo).to eq('foo') } - end - - it 'finds local variable from block definition in inner dsl scope' do - bar = 'bar' - outer { inner { expect(bar).to eq('bar') } } - end - end - - context 'instance variable lookup' do - it 'finds instance variable from block definition in outer dsl scope' do - @iv1 = 'iv1'; outer { expect(@iv1).to eq('iv1') } - end - - it "proxies instance variable assignments in block in outer dsl scope back into block's context" do - @iv1 = 'foo'; outer { @iv1 = 'bar' }; expect(@iv1).to eq('bar') - end - - it 'finds instance variable from block definition in inner dsl scope' do - @iv2 = 'iv2'; outer { inner { expect(@iv2).to eq('iv2') } } - end - - it "proxies instance variable assignments in block in inner dsl scope back into block's context" do - @iv2 = 'foo'; outer { inner { @iv2 = 'bar' } }; expect(@iv2).to eq('bar') - end - end - - end -
View file
_service:tar_scm:docile-1.1.5.gem/data/spec/spec_helper.rb
Deleted
@@ -1,30 +0,0 @@ -require File.expand_path('on_what', File.dirname(File.dirname(__FILE__))) - -begin - require 'simplecov' - require 'coveralls' - - # On Ruby 1.9+ use SimpleCov and publish to Coveralls.io - if !on_1_8? - SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter - SimpleCov::Formatter::HTMLFormatter, - Coveralls::SimpleCov::Formatter - - SimpleCov.start do - add_filter '/spec/' # exclude test code - add_filter '/vendor/' # exclude gems which are vendored on Travis CI - end - - # Remove Docile, which was required by SimpleCov, to require again later - Object.send(:remove_const, :Docile) - $LOADED_FEATURES.reject! { |f| f =~ /\/docile\// } - end -rescue LoadError - warn 'warning: simplecov/coveralls gems not found; skipping coverage' -end - -lib_dir = File.join(File.dirname(File.dirname(__FILE__)), 'lib') -$LOAD_PATH.unshift lib_dir unless $LOAD_PATH.include? lib_dir - -# Require Docile again, now with coverage enabled on 1.9+ -require 'docile'
View file
_service:tar_scm:docile-1.1.5.gem/checksums.yaml.gz -> _service:tar_scm:docile-1.4.0.gem/checksums.yaml.gz
Changed
@@ -1,7 +1,7 @@ --- -SHA1: - metadata.gz: 4df64881f4215d866d038e00f55d5b1ca2a45cb2 - data.tar.gz: 26a8de33f8bf657873666a2754bf09f605334e9d +SHA256: + metadata.gz: f4c79b9041a97cfbf6ee0a6d93a9e98a30cc188918d0916ed6b1321f8ac9dca6 + data.tar.gz: 772048f651fadb4277aaa0cb0b91b45e1b95be9f36b3654a9eb5db1a0bb143ea SHA512: - metadata.gz: 75669d4f578d70ba4c8be7dd6c19676041506e0f9408ba26ea0b1ad7931cf59636ccf36a4363ae709a1476464caba5ca1c429b07233dda7d797d5007f3c0af10 - data.tar.gz: e0e0e7364436ce92f4ab5efc52c2782e5da098d302652ca8698d74bcccc27c695b269c04ced3d224eec1a5b3833ba91c44232a2cc4c55fe061504246a715ef49 + metadata.gz: b4e3e7a9fcc953aed658c154dd6a4e43bc258e0895b6a5457f34a93dbcfd1d13808dc2a7d558b133515af695a9283f276d0f744dc57ed7caeae7394bb1ebe3c1 + data.tar.gz: 218c14f2cf80913d370376415f6c650e6c8d8eebfe8405f4529e820d3b2a46bf656ce45ca22ccb36a4409fffb31f823cea49515e1e21ed5c1584d66e55a9a550
View file
_service:tar_scm:docile-1.4.0.gem/data/.github/dependabot.yml
Added
@@ -0,0 +1,15 @@ +version: 2 + +updates: + + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + + # Maintain dependencies for Ruby's Bundler + - package-ecosystem: "bundler" + directory: "/" + schedule: + interval: "daily"
View file
_service:tar_scm:docile-1.4.0.gem/data/.github/workflows/main.yml
Added
@@ -0,0 +1,31 @@ +name: Main +on: + push: + branches: + - main + pull_request: + branches: + - main +jobs: + test: + name: 'CI Tests' + strategy: + fail-fast: false + matrix: + os: ubuntu-latest + # Due to https://github.com/actions/runner/issues/849, we have to use quotes for '3.0' + ruby: jruby, truffleruby, 2.5, 2.6, 2.7, '3.0', head + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v2.3.4 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + - run: bundle exec rspec + - uses: codecov/codecov-action@v1.5.0 + with: + name: ${{ matrix.ruby }} + file: ./coverage/coverage.xml + - run: bundle exec rubocop + if: matrix.ruby == '3.0'
View file
_service:tar_scm:docile-1.1.5.gem/data/.gitignore -> _service:tar_scm:docile-1.4.0.gem/data/.gitignore
Changed
@@ -6,4 +6,6 @@ doc .yardoc coverage -vendor \ No newline at end of file +vendor +.ruby-gemset +.ruby-version
View file
_service:tar_scm:docile-1.4.0.gem/data/.rubocop.yml
Added
@@ -0,0 +1,2 @@ +inherit_gem: + panolint: rubocop.yml
View file
_service:tar_scm:docile-1.1.5.gem/data/Gemfile -> _service:tar_scm:docile-1.4.0.gem/data/Gemfile
Changed
@@ -1,4 +1,26 @@ -source 'https://rubygems.org' +# frozen_string_literal: true + +source "https://rubygems.org" + +# CI-only dependencies go here +if ENV"CI" == "true" # rubocop:disable Style/IfUnlessModifier + gem "simplecov-cobertura", require: false, group: "test" +end # Specify gem's dependencies in docile.gemspec gemspec + +group :test do + gem "rspec", "~> 3.10" + gem "simplecov", require: false +end + +# Excluded from CI except on latest MRI Ruby, to reduce compatibility burden +group :checks do + gem "panolint", github: "panorama-ed/panolint", branch: "main" +end + +# Optional, only used locally to release to rubygems.org +group :release, optional: true do + gem "rake" +end
View file
_service:tar_scm:docile-1.1.5.gem/data/HISTORY.md -> _service:tar_scm:docile-1.4.0.gem/data/HISTORY.md
Changed
@@ -1,5 +1,71 @@ # HISTORY +## Unreleased changes(http://github.com/ms-ati/docile/compare/v1.4.0...main) + +## v1.4.0 (May 12, 2021)(http://github.com/ms-ati/docile/compare/v1.3.5...v1.4.0) + + - Special thanks to Matt Schreiber (@tomeon): + - Short-circuit to calling #instance_exec directly on the DSL object (prior to + constructing a proxy object) when the DSL object and block context object are + identical (*Sorry it took over a year to review and merge this!*) + - Renamed default branch from master to main, see: https://github.com/github/renaming + - Temporarily removed YARD doc configuration, to replace after + migration to Github Actions + - Removed support for all EOL Rubies < 2.6 + - Migrated CI from Travis to Github Actions + - Special thanks (again!) to Taichi Ishitani (@taichi-ishitani): + - Use more reliable codecov github action (via simplecov-cobertura) + rather than less reliable codecov gem + - Enable bundle caching in github action setup-ruby + - Added Rubocop, and configured it to run in CI + - Added Dependabot, and configured it to run daily + - Added SECURITY.md for vulnerability reporting policy + +## v1.3.5 (Jan 13, 2021)(http://github.com/ms-ati/docile/compare/v1.3.4...v1.3.5) + + - Special thanks to Jochen Seeber (@jochenseeber): + - Fix remaining delegation on Ruby 2.7 (PR #62) + - Remove support for Ruby 1.8.7 and REE, because they + are no longer runnable on Travis CI(https://travis-ci.community/t/ruby-1-8-7-and-ree-builds-broken-by-ssl-certificate-failure/10866) + - Announce that continued support for any EOL Ruby versions (that is, versions + prior to Ruby 2.5 as of Jan 13 2021) will be decided on **Feb 1, 2021** + based on comments to issue #58(https://github.com/ms-ati/docile/issues/58) + +## v1.3.4 (Dec 22, 2020)(http://github.com/ms-ati/docile/compare/v1.3.3...v1.3.4) + + - Special thanks to Benoit Daloze (@eregon): + - Fix delegation on Ruby 2.7 (issues #45 and #44, PR #52) + +## v1.3.3 (Dec 18, 2020)(http://github.com/ms-ati/docile/compare/v1.3.2...v1.3.3) + + - Special thanks (again!) to Taichi Ishitani (@taichi-ishitani): + - Fix keyword arg warnings on Ruby 2.7 (issue #44, PR #45) + - Filter Docile's source files from backtrace (issue #35, PR #36) + +## v1.3.2 (Jun 12, 2019)(http://github.com/ms-ati/docile/compare/v1.3.1...v1.3.2) + + - Special thanks (again!) to Taichi Ishitani (@taichi-ishitani): + - Fix for DSL object is replaced when #dsl_eval is nested (#33, PR #34) + +## v1.3.1 (May 24, 2018)(http://github.com/ms-ati/docile/compare/v1.3.0...v1.3.1) + + - Special thanks to Taichi Ishitani (@taichi-ishitani): + - Fix for when DSL object is also the block's context (#30) + +## v1.3.0 (Feb 7, 2018)(http://github.com/ms-ati/docile/compare/v1.2.0...v1.3.0) + + - Allow helper methods in block's context to call DSL methods + - Add SemVer release policy explicitly + - Standardize on double-quoted string literals + - Workaround some more Travis CI shenanigans + +## v1.2.0 (Jan 11, 2018)(http://github.com/ms-ati/docile/compare/v1.1.5...v1.2.0) + + - Special thanks to Christina Koller (@cmkoller) + - add DSL evaluation returning *return value of the block* (see `.dsl_eval_with_block_return`) + - add an example to README + - keep travis builds passing on old ruby versions + ## v1.1.5 (Jun 15, 2014)(http://github.com/ms-ati/docile/compare/v1.1.4...v1.1.5) - as much as possible, loosen version restrictions on development dependencies
View file
_service:tar_scm:docile-1.1.5.gem/data/LICENSE -> _service:tar_scm:docile-1.4.0.gem/data/LICENSE
Changed
@@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2012-2014 Marc Siegel +Copyright (c) 2012-2021 Marc Siegel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal
View file
_service:tar_scm:docile-1.1.5.gem/data/README.md -> _service:tar_scm:docile-1.4.0.gem/data/README.md
Changed
@@ -1,11 +1,15 @@ # Docile -!Gem Version(https://badge.fury.io/rb/docile.png)(http://badge.fury.io/rb/docile) -!Build Status(https://travis-ci.org/ms-ati/docile.png)(https://travis-ci.org/ms-ati/docile) -!Dependency Status(https://gemnasium.com/ms-ati/docile.png)(https://gemnasium.com/ms-ati/docile) -!Code Climate(https://codeclimate.com/github/ms-ati/docile.png)(https://codeclimate.com/github/ms-ati/docile) -!Coverage Status(https://coveralls.io/repos/ms-ati/docile/badge.png)(https://coveralls.io/r/ms-ati/docile) -!Inline docs(http://inch-ci.org/github/ms-ati/docile.png)(http://inch-ci.org/github/ms-ati/docile) -!Bitdeli Badge(https://d2weczhvl823v0.cloudfront.net/ms-ati/docile/trend.png)(https://bitdeli.com/free "Bitdeli Badge") + +!Gem Version(https://img.shields.io/gem/v/docile.svg)(https://rubygems.org/gems/docile) +!Gem Downloads(https://img.shields.io/gem/dt/docile.svg)(https://rubygems.org/gems/docile) + +!Join the chat at https://gitter.im/ms-ati/docile(https://badges.gitter.im/Join%20Chat.svg)(https://gitter.im/ms-ati/docile?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +!Yard Docs(http://img.shields.io/badge/yard-docs-blue.svg)(http://rubydoc.info/github/ms-ati/docile) +!Docs Coverage(http://inch-ci.org/github/ms-ati/docile.png)(http://inch-ci.org/github/ms-ati/docile) + +!Build Status(https://github.com/ms-ati/docile/actions/workflows/main.yml/badge.svg)(https://github.com/ms-ati/docile/actions/workflows/main.yml) +!Code Coverage(https://img.shields.io/codecov/c/github/ms-ati/docile.svg)(https://codecov.io/github/ms-ati/docile) +!Maintainability(https://api.codeclimate.com/v1/badges/79ca631bc123f7b83b34/maintainability)(https://codeclimate.com/github/ms-ati/docile/maintainability) Ruby makes it possible to create very expressive **Domain Specific Languages**, or **DSL**'s for short. However, it requires some deep knowledge and @@ -20,7 +24,7 @@ ## Usage -### Basic +### Basic: Ruby Array(http://ruby-doc.org/core-3.0.0/Array.html) as DSL Let's say that we want to make a DSL for modifying Array objects. Wouldn't it be great if we could just treat the methods of Array as a DSL? @@ -45,7 +49,80 @@ Easy! -### Advanced +### Next step: Allow helper methods to call DSL methods + +What if, in our use of the methods of Array as a DSL, we want to extract +helper methods which in turn call DSL methods? + +```ruby +def pop_sum_and_push(n) + sum = 0 + n.times { sum += pop } + push sum +end + +Docile.dsl_eval() do + push 5 + push 6 + pop_sum_and_push(2) +end +#=> 11 +``` + +Without Docile, you may find this sort of code extraction to be more +challenging. + +### Wait! Can't I do that with just `instance_eval` or `instance_exec`? + +Good question! + +In short: **No**. + +Not if you want the code in the block to be able to refer to anything +the block would normally have access to from the surrounding context. + +Let's be very specific. Docile internally uses `instance_exec` (see execution.rb#26(lib/docile/execution.rb#L26)), adding a small layer to support referencing *local variables*, *instance variables*, and *methods* from the _block's context_ **or** the target _object's context_, interchangeably. This is "**the hard part**", where most folks making a DSL in Ruby throw up their hands. + +For example: + +```ruby +class ContextOfBlock + def example_of_contexts + @block_instance_var = 1 + block_local_var = 2 + + with_array do + push @block_instance_var + push block_local_var + pop + push block_sees_this_method + end + end + + def block_sees_this_method + 3 + end + + def with_array(&block) + { + docile: Docile.dsl_eval(, &block), + instance_eval: (.instance_eval(&block) rescue $!), + instance_exec: (.instance_exec(&block) rescue $!) + } + end +end + +ContextOfBlock.new.example_of_contexts +#=> { + :docile=>1, 3, + :instance_eval=>#<NameError: undefined local variable or method `block_sees_this_method' for nil:Array>, + :instance_exec=>#<NameError: undefined local variable or method `block_sees_this_method' for nil:Array> + } +``` + +As you can see, it won't be possible to call methods or access instance variables defined in the block's context using just the raw `instance_eval` or `instance_exec` methods. And in fact, Docile goes further, making it easy to maintain this support even in multi-layered DSLs. + +### Build a Pizza Mutating (changing) an Array instance is fine, but what usually makes a good DSL is a Builder Pattern2. @@ -83,7 +160,7 @@ Then implement your DSL like this: -``` ruby +```ruby def pizza(&block) Docile.dsl_eval(PizzaBuilder.new, &block).build end @@ -93,6 +170,38 @@ 2: http://stackoverflow.com/questions/328496/when-would-you-use-the-builder-pattern "Builder Pattern" +### Multi-level and Recursive DSLs + +Docile is a very easy way to write a multi-level DSL in Ruby, even for +a recursive data structure such as a tree4: + +```ruby +Person = Struct.new(:name, :mother, :father) + +person { + name 'John Smith' + mother { + name 'Mary Smith' + } + father { + name 'Tom Smith' + mother { + name 'Jane Smith' + } + } +} + +#=> #<struct Person name="John Smith", +# mother=#<struct Person name="Mary Smith", mother=nil, father=nil>, +# father=#<struct Person name="Tom Smith", +# mother=#<struct Person name="Jane Smith", mother=nil, father=nil>, +# father=nil>> +``` + +See the full person tree example4 for details. + +4: https://gist.github.com/ms-ati/2bb17bdf10a430faba98 + ### Block parameters Parameters can be passed to the DSL block. @@ -153,18 +262,18 @@ 3: http://www.sinatrarb.com "Sinatra" -### Functional-Style DSL Objects +### Functional-Style Immutable DSL Objects Sometimes, you want to use an object as a DSL, but it doesn't quite fit the imperative(http://en.wikipedia.org/wiki/Imperative_programming) pattern shown above. Instead of methods like -Array#push(http://www.ruby-doc.org/core-2.0/Array.html#method-i-push), which +Array#push(http://www.ruby-doc.org/core-3.0.0/Array.html#method-i-push), which modifies the object at hand, it has methods like -String#reverse(http://www.ruby-doc.org/core-2.0/String.html#method-i-reverse), +String#reverse(http://www.ruby-doc.org/core-3.0.0/String.html#method-i-reverse), which returns a new object without touching the original. Perhaps it's even -frozen(http://www.ruby-doc.org/core-2.0/Object.html#method-i-freeze) in +frozen(http://www.ruby-doc.org/core-3.0.0/Object.html#method-i-freeze) in order to enforce immutability(http://en.wikipedia.org/wiki/Immutable_object). Wouldn't it be great if we could just treat these methods as a DSL as well? @@ -192,6 +301,33 @@ All set! +### Accessing the block's return value + +Sometimes you might want to access the return value of your provided block, +as opposed to the DSL object itself. In these cases, use +`dsl_eval_with_block_return`. It behaves exactly like `dsl_eval`, but returns +the output from executing the block, rather than the DSL object. + +```ruby +arr = +with_array(arr) do + push "a"
View file
_service:tar_scm:docile-1.1.5.gem/data/Rakefile -> _service:tar_scm:docile-1.4.0.gem/data/Rakefile
Changed
@@ -1,28 +1,14 @@ -require 'rake/clean' -require 'bundler/gem_tasks' -require 'rspec/core/rake_task' -require File.expand_path('on_what', File.dirname(__FILE__)) +# frozen_string_literal: true + +require "rake/clean" +require "bundler/gem_tasks" +require "rspec/core/rake_task" # Default task for `rake` is to run rspec -task :default => :spec +task default: :spec # Use default rspec rake task RSpec::Core::RakeTask.new # Configure `rake clobber` to delete all generated files -CLOBBER.include('pkg', 'doc', 'coverage') - -# To limit needed compatibility with versions of dependencies, only configure -# yard doc generation when *not* on Travis, JRuby, or 1.8 -if !on_travis? && !on_jruby? && !on_1_8? - require 'github/markup' - require 'redcarpet' - require 'yard' - require 'yard/rake/yardoc_task' - - YARD::Rake::YardocTask.new do |t| - OTHER_PATHS = %w() - t.files = 'lib/**/*.rb', OTHER_PATHS - t.options = %w(--markup-provider=redcarpet --markup=markdown --main=README.md) - end -end +CLOBBER.include("pkg", "doc", "coverage")
View file
_service:tar_scm:docile-1.4.0.gem/data/SECURITY.md
Added
@@ -0,0 +1,18 @@ +# Security Policy + +## Supported Versions + +Use this section to tell people about which versions of your project are +currently being supported with security updates. + +| Version | Supported | +| ------- | ------------------ | +| 1.3.x | :white_check_mark: | +| < 1.3 | :x: | + +## Reporting a Vulnerability + +At this time, security issues and vulnerabilities in Docile should +be reported like any other issue. Please create an issue in the +public issue tracker(https://github.com/ms-ati/docile/issues) on +Github.
View file
_service:tar_scm:docile-1.1.5.gem/data/docile.gemspec -> _service:tar_scm:docile-1.4.0.gem/data/docile.gemspec
Changed
@@ -1,43 +1,29 @@ -require File.expand_path('on_what', File.dirname(__FILE__)) -$:.push File.expand_path('../lib', __FILE__) -require 'docile/version' +# frozen_string_literal: true + +require_relative "lib/docile/version" Gem::Specification.new do |s| - s.name = 'docile' + s.name = "docile" s.version = Docile::VERSION - s.author = 'Marc Siegel' - s.email = 'marc@usainnov.com' - s.homepage = 'https://ms-ati.github.io/docile/' - s.summary = 'Docile keeps your Ruby DSLs tame and well-behaved' - s.description = 'Docile turns any Ruby object into a DSL. Especially useful with the Builder pattern.' - s.license = 'MIT' - - # Files included in the gem - s.files = `git ls-files`.split("\n") - s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") - s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } - s.require_paths = %w(lib) - - # Specify oldest supported Ruby version - s.required_ruby_version = '>= 1.8.7' + s.author = "Marc Siegel" + s.email = "marc@usainnov.com" + s.homepage = "https://ms-ati.github.io/docile/" + s.summary = "Docile keeps your Ruby DSLs tame and well-behaved." + s.description = "Docile treats the methods of a given ruby object as a DSL " \ + "(domain specific language) within a given block. \n\n" \ + "Killer feature: you can also reference methods, instance " \ + "variables, and local variables from the original (non-DSL) "\ + "context within the block. \n\n" \ + "Docile releases follow Semantic Versioning as defined at " \ + "semver.org." + s.license = "MIT" - # Run rspec tests from rake - s.add_development_dependency 'rake' - s.add_development_dependency 'rspec', '~> 3.0.0' + # Specify oldest supported Ruby version (2.5 to support JRuby 9.2.17.0) + s.required_ruby_version = ">= 2.5.0" - # NOTE: needed for Travis builds on 1.8, but can't yet reproduce failure locally - s.add_development_dependency 'mime-types', '~> 1.25.1' if on_1_8? - - # To limit needed compatibility with versions of dependencies, only configure - # yard doc generation when *not* on Travis, JRuby, or 1.8 - if !on_travis? && !on_jruby? && !on_1_8? - # Github flavored markdown in YARD documentation - # http://blog.nikosd.com/2011/11/github-flavored-markdown-in-yard.html - s.add_development_dependency 'yard' - s.add_development_dependency 'redcarpet' - s.add_development_dependency 'github-markup' + # Files included in the gem + s.files = `git ls-files -z`.split("\x0").reject do |f| + f.match(%r{^(test|spec|features)/}) end - - # Coveralls test coverage tool, basically hosted SimpleCov - s.add_development_dependency 'coveralls' + s.require_paths = "lib" end
View file
_service:tar_scm:docile-1.1.5.gem/data/lib/docile.rb -> _service:tar_scm:docile-1.4.0.gem/data/lib/docile.rb
Changed
@@ -1,7 +1,10 @@ -require 'docile/version' -require 'docile/execution' -require 'docile/fallback_context_proxy' -require 'docile/chaining_fallback_context_proxy' +# frozen_string_literal: true + +require "docile/version" +require "docile/execution" +require "docile/fallback_context_proxy" +require "docile/chaining_fallback_context_proxy" +require "docile/backtrace_filter" # Docile keeps your Ruby DSLs tame and well-behaved. module Docile @@ -43,8 +46,53 @@ exec_in_proxy_context(dsl, FallbackContextProxy, *args, &block) dsl end + + ruby2_keywords :dsl_eval if respond_to?(:ruby2_keywords, true) module_function :dsl_eval + # Execute a block in the context of an object whose methods represent the + # commands in a DSL, and return *the block's return value*. + # + # @note Use with an *imperative* DSL (commands modify the context object) + # + # Use this method to execute an *imperative* DSL, which means that: + # + # 1. Each command mutates the state of the DSL context object + # 2. The return value of each command is ignored + # 3. The final return value is the original context object + # + # @example Use a String as a DSL + # Docile.dsl_eval_with_block_return("Hello, world!") do + # reverse! + # upcase! + # first + # end + # #=> "!" + # + # @example Use an Array as a DSL + # Docile.dsl_eval_with_block_return() do + # push "a" + # push "b" + # pop + # push "c" + # length + # end + # #=> 2 + # + # @param dsl Object context object whose methods make up the DSL + # @param args Array arguments to be passed to the block + # @param block Proc the block of DSL commands to be executed against the + # `dsl` context object + # @return Object the return value from executing the block + def dsl_eval_with_block_return(dsl, *args, &block) + exec_in_proxy_context(dsl, FallbackContextProxy, *args, &block) + end + + if respond_to?(:ruby2_keywords, true) + ruby2_keywords :dsl_eval_with_block_return + end + module_function :dsl_eval_with_block_return + # Execute a block in the context of an immutable object whose methods, # and the methods of their return values, represent the commands in a DSL. # @@ -80,5 +128,7 @@ def dsl_eval_immutable(dsl, *args, &block) exec_in_proxy_context(dsl, ChainingFallbackContextProxy, *args, &block) end + + ruby2_keywords :dsl_eval_immutable if respond_to?(:ruby2_keywords, true) module_function :dsl_eval_immutable end
View file
_service:tar_scm:docile-1.4.0.gem/data/lib/docile/backtrace_filter.rb
Added
@@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Docile + # @api private + # + # This is used to remove entries pointing to Docile's source files + # from {Exception#backtrace} and {Exception#backtrace_locations}. + # + # If {NoMethodError} is caught then the exception object will be extended + # by this module to add filter functionalities. + module BacktraceFilter + FILTER_PATTERN = %r{/lib/docile/}.freeze + + def backtrace + super.reject { |trace| trace =~ FILTER_PATTERN } + end + + if ::Exception.public_method_defined?(:backtrace_locations) + def backtrace_locations + super.reject { |location| location.absolute_path =~ FILTER_PATTERN } + end + end + end +end
View file
_service:tar_scm:docile-1.1.5.gem/data/lib/docile/chaining_fallback_context_proxy.rb -> _service:tar_scm:docile-1.4.0.gem/data/lib/docile/chaining_fallback_context_proxy.rb
Changed
@@ -1,4 +1,6 @@ -require 'docile/fallback_context_proxy' +# frozen_string_literal: true + +require "docile/fallback_context_proxy" module Docile # @api private @@ -10,11 +12,16 @@ # objects. # # @see Docile.dsl_eval_immutable + # + # rubocop:disable Style/MissingRespondToMissing class ChainingFallbackContextProxy < FallbackContextProxy # Proxy methods as in {FallbackContextProxy#method_missing}, replacing # `receiver` with the returned value. def method_missing(method, *args, &block) @__receiver__ = super(method, *args, &block) end + + ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true) end -end \ No newline at end of file + # rubocop:enable Style/MissingRespondToMissing +end
View file
_service:tar_scm:docile-1.1.5.gem/data/lib/docile/execution.rb -> _service:tar_scm:docile-1.4.0.gem/data/lib/docile/execution.rb
Changed
@@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Docile # @api private # @@ -15,21 +17,37 @@ # @param block Proc the block of DSL commands to be executed # @return Object the return value of the block def exec_in_proxy_context(dsl, proxy_type, *args, &block) - block_context = eval('self', block.binding) + block_context = eval("self", block.binding) # rubocop:disable Style/EvalWithLocation + + # Use #equal? to test strict object identity (assuming that this dictum + # from the Ruby docs holds: "unlike ==, the equal? method should never + # be overridden by subclasses as it is used to determine object + # identity") + return dsl.instance_exec(*args, &block) if dsl.equal?(block_context) + proxy_context = proxy_type.new(dsl, block_context) begin block_context.instance_variables.each do |ivar| value_from_block = block_context.instance_variable_get(ivar) proxy_context.instance_variable_set(ivar, value_from_block) end + proxy_context.instance_exec(*args, &block) ensure + if block_context.respond_to?(:__docile_undo_fallback__) + block_context.send(:__docile_undo_fallback__) + end + block_context.instance_variables.each do |ivar| + next unless proxy_context.instance_variables.include?(ivar) + value_from_dsl_proxy = proxy_context.instance_variable_get(ivar) block_context.instance_variable_set(ivar, value_from_dsl_proxy) end end end + + ruby2_keywords :exec_in_proxy_context if respond_to?(:ruby2_keywords, true) module_function :exec_in_proxy_context end -end \ No newline at end of file +end
View file
_service:tar_scm:docile-1.1.5.gem/data/lib/docile/fallback_context_proxy.rb -> _service:tar_scm:docile-1.4.0.gem/data/lib/docile/fallback_context_proxy.rb
Changed
@@ -1,4 +1,6 @@ -require 'set' +# frozen_string_literal: true + +require "set" module Docile # @api private @@ -13,14 +15,20 @@ # This is useful for implementing DSL evaluation in the context of an object. # # @see Docile.dsl_eval + # + # rubocop:disable Style/MissingRespondToMissing class FallbackContextProxy # The set of methods which will **not** be proxied, but instead answered # by this object directly. NON_PROXIED_METHODS = Set:__send__, :object_id, :__id__, :==, :equal?, - :'!', :'!=', :instance_exec, :instance_variables, + :!, :!=, :instance_exec, :instance_variables, :instance_variable_get, :instance_variable_set, :remove_instance_variable + # The set of methods which will **not** fallback from the block's context + # to the dsl object. + NON_FALLBACK_METHODS = Set:class, :self, :respond_to?, :instance_of? + # The set of instance variables which are local to this object and hidden. # All other instance variables will be copied in and out of this object # from the scope in which this proxy was created. @@ -38,16 +46,44 @@ def initialize(receiver, fallback) @__receiver__ = receiver @__fallback__ = fallback + + # Enables calling DSL methods from helper methods in the block's context + unless fallback.respond_to?(:method_missing) + # NOTE: We could switch to {#define_singleton_method} on current Rubies + singleton_class = (class << fallback; self; end) + + # instrument {#method_missing} on the block's context to fallback to + # the DSL object. This allows helper methods in the block's context to + # contain calls to methods on the DSL object. + singleton_class. + send(:define_method, :method_missing) do |method, *args, &block| + m = method.to_sym + if !NON_FALLBACK_METHODS.member?(m) && + !fallback.respond_to?(m) && + receiver.respond_to?(m) + receiver.__send__(method.to_sym, *args, &block) + else + super(method, *args, &block) + end + end + + if singleton_class.respond_to?(:ruby2_keywords, true) + singleton_class.send(:ruby2_keywords, :method_missing) + end + + # instrument a helper method to remove the above instrumentation + singleton_class. + send(:define_method, :__docile_undo_fallback__) do + singleton_class.send(:remove_method, :method_missing) + singleton_class.send(:remove_method, :__docile_undo_fallback__) + end + end end # @return Array<Symbol> Instance variable names, excluding # {NON_PROXIED_INSTANCE_VARIABLES} - # - # @note on Ruby 1.8.x, the instance variable names are actually of - # type `String`. def instance_variables - # Ruby 1.8.x returns string names, convert to symbols for compatibility - super.select { |v| !NON_PROXIED_INSTANCE_VARIABLES.include?(v.to_sym) } + super.reject { |v| NON_PROXIED_INSTANCE_VARIABLES.include?(v) } end # Proxy all methods, excluding {NON_PROXIED_METHODS}, first to `receiver` @@ -56,8 +92,16 @@ if @__receiver__.respond_to?(method.to_sym) @__receiver__.__send__(method.to_sym, *args, &block) else - @__fallback__.__send__(method.to_sym, *args, &block) + begin + @__fallback__.__send__(method.to_sym, *args, &block) + rescue NoMethodError => e + e.extend(BacktraceFilter) + raise e + end end end + + ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true) end + # rubocop:enable Style/MissingRespondToMissing end
View file
_service:tar_scm:docile-1.1.5.gem/data/lib/docile/version.rb -> _service:tar_scm:docile-1.4.0.gem/data/lib/docile/version.rb
Changed
@@ -1,4 +1,6 @@ +# frozen_string_literal: true + module Docile # The current version of this library - VERSION = '1.1.5' + VERSION = "1.4.0" end
View file
_service:tar_scm:docile-1.1.5.gem/metadata.gz -> _service:tar_scm:docile-1.4.0.gem/metadata.gz
Changed
@@ -1,131 +1,48 @@ --- !ruby/object:Gem::Specification name: docile version: !ruby/object:Gem::Version - version: 1.1.5 + version: 1.4.0 platform: ruby authors: - Marc Siegel -autorequire: +autorequire: bindir: bin cert_chain: -date: 2014-06-15 00:00:00.000000000 Z -dependencies: -- !ruby/object:Gem::Dependency - name: rake - requirement: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' - type: :development - prerelease: false - version_requirements: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' -- !ruby/object:Gem::Dependency - name: rspec - requirement: !ruby/object:Gem::Requirement - requirements: - - - "~>" - - !ruby/object:Gem::Version - version: 3.0.0 - type: :development - prerelease: false - version_requirements: !ruby/object:Gem::Requirement - requirements: - - - "~>" - - !ruby/object:Gem::Version - version: 3.0.0 -- !ruby/object:Gem::Dependency - name: yard - requirement: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' - type: :development - prerelease: false - version_requirements: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' -- !ruby/object:Gem::Dependency - name: redcarpet - requirement: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' - type: :development - prerelease: false - version_requirements: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' -- !ruby/object:Gem::Dependency - name: github-markup - requirement: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' - type: :development - prerelease: false - version_requirements: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' -- !ruby/object:Gem::Dependency - name: coveralls - requirement: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' - type: :development - prerelease: false - version_requirements: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' -description: Docile turns any Ruby object into a DSL. Especially useful with the Builder - pattern. +date: 2021-05-12 00:00:00.000000000 Z +dependencies: +description: "Docile treats the methods of a given ruby object as a DSL (domain specific + language) within a given block. \n\nKiller feature: you can also reference methods, + instance variables, and local variables from the original (non-DSL) context within + the block. \n\nDocile releases follow Semantic Versioning as defined at semver.org." email: marc@usainnov.com executables: extensions: extra_rdoc_files: files: +- ".github/dependabot.yml" +- ".github/workflows/main.yml" - ".gitignore" - ".rspec" -- ".ruby-gemset" -- ".ruby-version" -- ".travis.yml" +- ".rubocop.yml" - ".yardopts" - Gemfile - HISTORY.md - LICENSE - README.md - Rakefile +- SECURITY.md - docile.gemspec - lib/docile.rb +- lib/docile/backtrace_filter.rb - lib/docile/chaining_fallback_context_proxy.rb - lib/docile/execution.rb - lib/docile/fallback_context_proxy.rb - lib/docile/version.rb -- on_what.rb -- spec/docile_spec.rb -- spec/spec_helper.rb homepage: https://ms-ati.github.io/docile/ licenses: - MIT metadata: {} -post_install_message: +post_install_message: rdoc_options: require_paths: - lib @@ -133,19 +50,15 @@ requirements: - - ">=" - !ruby/object:Gem::Version - version: 1.8.7 + version: 2.5.0 required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' requirements: -rubyforge_project: -rubygems_version: 2.2.2 -signing_key: +rubygems_version: 3.2.3 +signing_key: specification_version: 4 -summary: Docile keeps your Ruby DSLs tame and well-behaved -test_files: -- spec/docile_spec.rb -- spec/spec_helper.rb -has_rdoc: +summary: Docile keeps your Ruby DSLs tame and well-behaved. +test_files:
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2