keyword_params 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rvmrc ADDED
@@ -0,0 +1,7 @@
1
+
2
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
3
+ && -s "${rvm_path:-$HOME/.rvm}/environments/ruby-1.9.2-p0@keyword_params" ]] ; then
4
+ \. "${rvm_path:-$HOME/.rvm}/environments/ruby-1.9.2-p0@keyword_params"
5
+ else
6
+ rvm --create "ruby-1.9.2-p0@keyword_params"
7
+ fi
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in keyword_params.gemspec
4
+ gemspec
data/README ADDED
@@ -0,0 +1 @@
1
+ Please see example.rb!
@@ -0,0 +1,42 @@
1
+ require 'English'
2
+ require 'bundler'
3
+
4
+ LIB_PATH = File.expand_path("lib", File.dirname(__FILE__))
5
+ EXAMPLE_FILE = File.expand_path("example.rb", File.dirname(__FILE__))
6
+
7
+ Bundler::GemHelper.install_tasks
8
+
9
+ task "load_path" do
10
+ $LOAD_PATH.unshift(File.expand_path("lib", File.dirname(__FILE__)))
11
+ end
12
+
13
+ desc "Run the tests"
14
+ task "test" => %w[load_path] do
15
+ require 'rcodetools/xmpfilter'
16
+ require 'rcodetools/options'
17
+ include Rcodetools
18
+ example_file = EXAMPLE_FILE
19
+ example_code = File.read(example_file)
20
+ xmp_options = {
21
+ include_paths: [LIB_PATH]
22
+ }
23
+ output = ::XMPFilter.run(example_code,xmp_options)
24
+ diff = IO.popen("diff #{example_file} -", "r+")
25
+ diff.write(output)
26
+ diff.close_write
27
+ results = diff.read
28
+ diff.close_read
29
+ if $CHILD_STATUS.success?
30
+ puts "Green!"
31
+ exit 0
32
+ else
33
+ puts results
34
+ exit 1
35
+ end
36
+ end
37
+
38
+ desc "Run the examples"
39
+ task "example" do
40
+ $LOAD_PATH.unshift(LIB_PATH)
41
+ load EXAMPLE_FILE
42
+ end
@@ -0,0 +1,77 @@
1
+ # Ruby doesn't have keyword arguments, but it fakes them pretty well.
2
+
3
+ def explain(options={})
4
+ "the #{options[:the]} says #{options[:says]}"
5
+ end
6
+
7
+ explain the: "pig", says: "oink" # => "the pig says oink"
8
+ explain the: "frog", says: "ribbit" # => "the frog says ribbit"
9
+
10
+ # Which is fine, but it isn't as declarative (and therefore not as
11
+ # self-documenting) as proper keyword arguments.
12
+
13
+ # Also, when using keywords to construct English-like DSLs, as we are
14
+ # above, we often would like to assign different names to the
15
+ # parameters which are passed by keyword.
16
+
17
+ def explain2(options={})
18
+ animal = options[:the]
19
+ sound = options[:says]
20
+ "the #{animal} says #{sound}"
21
+ end
22
+
23
+ # And then there's defaulting for missing paramters...
24
+
25
+ def explain3(options={})
26
+ animal = options.fetch(:the) { "cow" }
27
+ sound = options.fetch(:says){ "moo" }
28
+ "the #{animal} says #{sound}"
29
+ end
30
+
31
+ explain3 # => "the cow says moo"
32
+
33
+ # Of course, it might be nice to offer a positional-argument version
34
+ # as well.
35
+
36
+ def explain4(*args)
37
+ options = args.last.is_a?(Hash) ? args.pop : {}
38
+ animal = args[0] || options.fetch(:the) { "cow" }
39
+ sound = args[1] || options.fetch(:says){ "moo" }
40
+ "the #{animal} says #{sound}"
41
+ end
42
+
43
+ explain4 "horse", "neigh" # => "the horse says neigh"
44
+ explain4 "duck", says: "quack" # => "the duck says quack"
45
+ explain4 the: "donkey", :says => "hee-haw" # => "the donkey says hee-haw"
46
+
47
+ # Once we've written all this parameter-munging machinery, we then
48
+ # repeat it in the method's documentation. (Assuming we document it at
49
+ # all). This seems a bit un-DRY.
50
+
51
+ # Let's see if we can improve on the situation.
52
+
53
+ require 'keyword_params'
54
+
55
+ class BarnYard
56
+ extend KeywordParams
57
+
58
+ keyword(:the) { "cow" }
59
+ keyword(:says) { "moo" }
60
+ def explain(animal, sound)
61
+ "the #{animal} says #{sound}"
62
+ end
63
+ end
64
+
65
+ b = BarnYard.new
66
+
67
+ b.explain "horse", "neigh" # => "the horse says neigh"
68
+ b.explain "duck", says: "quack" # => "the duck says quack"
69
+ b.explain the: "donkey", :says => "hee-haw" # => "the donkey says hee-haw"
70
+ b.explain the: "cat" # => "the cat says moo"
71
+ b.explain # => "the cow says moo"
72
+
73
+ # Improvement? Well, I'll leave that for you to judge. Certainly
74
+ # specifying part of the method's signature above the method
75
+ # definition proper has a nasty "old-style C" feel to it. But I feel
76
+ # like it's a lot more self-documenting than doing the keyword
77
+ # processing inside the method.
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "keyword_params/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "keyword_params"
7
+ s.version = KeywordParams::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Avdi Grimm"]
10
+ s.email = ["avdi@avdi.org"]
11
+ s.homepage = ""
12
+ s.summary = %q{Declarative keyword arguments for methods}
13
+ s.description = %q{Declarative keyword arguments for methods}
14
+
15
+ s.rubyforge_project = "keyword_params"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_development_dependency 'rcodetools'
23
+ end
@@ -0,0 +1,42 @@
1
+ require 'ostruct'
2
+ module KeywordParams
3
+ class KeywordList
4
+ def initialize
5
+ @keywords = []
6
+ end
7
+
8
+ def add_keyword(name, default_block)
9
+ @keywords << OpenStruct.new(name: name, default_block: default_block)
10
+ end
11
+
12
+ def values(options={})
13
+ @keywords.map {|keyword|
14
+ options.fetch(keyword.name, &keyword.default_block)
15
+ }
16
+ end
17
+ end
18
+
19
+ def keyword(name, &default_block)
20
+ @keyword_list ||= KeywordList.new
21
+ @keyword_list.add_keyword(name, default_block)
22
+ end
23
+
24
+ def method_added(name)
25
+ # Avoid crazy stack recursion
26
+ return if Thread.current[:in_keyword_params_method_added]
27
+ Thread.current[:in_keyword_params_method_added] = true
28
+ original_method = instance_method(name)
29
+ keyword_list = @keyword_list
30
+ @keyword_list = nil
31
+ define_method(name) do |*args|
32
+ options = args.last.is_a?(Hash) ? args.pop : {}
33
+ keyword_args = keyword_list.values(options)
34
+ # We only need keyword arg values for as many positional args
35
+ # as are NOT supplied.
36
+ needed_keyword_args = keyword_args[(args.size..-1)]
37
+ original_method.bind(self).call(*(args + needed_keyword_args))
38
+ end
39
+ super
40
+ Thread.current[:in_keyword_params_method_added] = false
41
+ end
42
+ end
@@ -0,0 +1,3 @@
1
+ module KeywordParams
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: keyword_params
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Avdi Grimm
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-09-29 00:00:00 -04:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rcodetools
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ type: :development
26
+ version_requirements: *id001
27
+ description: Declarative keyword arguments for methods
28
+ email:
29
+ - avdi@avdi.org
30
+ executables: []
31
+
32
+ extensions: []
33
+
34
+ extra_rdoc_files: []
35
+
36
+ files:
37
+ - .gitignore
38
+ - .rvmrc
39
+ - Gemfile
40
+ - README
41
+ - Rakefile
42
+ - example.rb
43
+ - keyword_params.gemspec
44
+ - lib/keyword_params.rb
45
+ - lib/keyword_params/version.rb
46
+ has_rdoc: true
47
+ homepage: ""
48
+ licenses: []
49
+
50
+ post_install_message:
51
+ rdoc_options: []
52
+
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ requirements: []
68
+
69
+ rubyforge_project: keyword_params
70
+ rubygems_version: 1.5.2
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: Declarative keyword arguments for methods
74
+ test_files: []
75
+