such 0.2.0 → 2.0.210201

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2aa58153d86bf6074ae44f9ddb9b0d75f2974425
4
- data.tar.gz: b62521c79d8f591ce2bfd0cd7365ab419c8bb99c
2
+ SHA256:
3
+ metadata.gz: 84767a253e3e1535798068135516617e3c198fc4b3ed756e529c16c27f25a649
4
+ data.tar.gz: 919ffcc84f13208bb3fc232ad8dc2ac92eb16b40d0cc6f63bb81b2b79c8b7e63
5
5
  SHA512:
6
- metadata.gz: 784228d9e8176604fcb782f4a4ebca93d58e80292b261cf624659f1d5595e9cb089aa8f21dcabb106ef41eb3d44dc2ca8e3c020e6bacc682b325b86bff02abe7
7
- data.tar.gz: 3298e0be3b96149b0433fc59cd54b9934338ecb7cd1befeff07e3153c45d2671ebd48bf34b468194861bcab16791b49e2f16ea846dfd68fbc9e7909a7bdc0fd7
6
+ metadata.gz: d53f03a3dc85ad766199e40d0f7d08011420ec1c437de865cdda76f2757a8c4bac012379098fd087af1f78ce11918be949b46fe0cff68668806df237a175a5f0
7
+ data.tar.gz: 96c391adf17465cdf4330a37c83eece66a1d4ae37337067fc8b04cd1f0105fe5f4b45b4863371c60d558552980e5ab744f9cb817c4c26322895b50139567760a
@@ -1,54 +1,77 @@
1
- = Such
1
+ # Such
2
2
 
3
- == DESCRIPTION:
3
+ * [VERSION 2.0.210201](https://github.com/carlosjhr64/such/releases)
4
+ * [github](https://www.github.com/carlosjhr64/such)
5
+ * [rubygems](https://rubygems.org/gems/such)
4
6
 
5
- Wraps Ruby's Gtk widgets with an alternate constructor
7
+ ## DESCRIPTION:
8
+
9
+ Wraps widgets with an alternate constructor
6
10
  which factors out the configuration and assembly procedures into metadata.
11
+ Can be used to wrap any class with the alternate constructor,
12
+ although targeted only Gtk3 widgets.
13
+
14
+ ## INSTALL:
7
15
 
8
- And the _Such_ module can be used to wrap any class with the alternate constructor,
9
- although currently only _Gtk3_ widgets is supported.
16
+ ```shell
17
+ $ sudo gem install such
18
+ ```
10
19
 
11
- == SYNOPSIS:
20
+ ## SYNOPSIS:
12
21
 
13
- require 'gtk3'
14
- require 'such'
15
- include Such; Things.gtk_widget
22
+ ```ruby
23
+ require 'gtk3'
24
+ require 'such'
25
+ include Such; Things.in Gtk::Widget
16
26
 
17
- Thing.configure window: {
18
- set_title: 'Synopsis Example',
19
- set_window_position: :center },
20
- BUTTON: [label: 'Button!'],
21
- button: {set_size_request: [100,50], into:[:add]}
27
+ Thing.configure window: {
28
+ set_title: 'Synopsis Example',
29
+ set_window_position: :center},
30
+ BUTTON: [label: 'Button!'],
31
+ button: {
32
+ set_size_request: [100,50],
33
+ into:[:add]}
22
34
 
23
- window = Window.new(:window, 'destroy'){Gtk.main_quit}
24
- Button.new(window, :button!){puts 'Button pressed!'}
25
- window.show_all
35
+ window = Window.new(:window, 'destroy'){Gtk.main_quit} #~> Such::Window
36
+ Button.new(window, :button!){puts 'Button pressed!'} #~> Such::Button
37
+ window.show_all
26
38
 
27
- Gtk.main
39
+ Gtk.main #=> nil
40
+ ```
28
41
 
29
- == MORE:
42
+ ## MORE:
30
43
 
31
44
  Arrays are passed to constructer's super,
32
45
  Hashes are method=>arguments pairs, and Strings are signals.
33
46
  Other objects are assumed to be containers:
34
47
 
35
- Such::Button.new(window, [label: 'Hello!'], {set_size_request:[100,50]}, 'clicked' ){puts 'OK'}
48
+ ```ruby
49
+ Such::Button.new(
50
+ window,
51
+ [label: 'Hello!'],
52
+ {set_size_request:[100,50]},
53
+ 'clicked'
54
+ ){ puts 'OK'}
36
55
 
37
- # Is equivalent to
56
+ # Is equivalent to:
38
57
 
39
- button = Gtk::Button.new(label:'Hello!')
40
- window.add button
41
- button.set_size_request 100, 50
42
- button.signal_connect('clicked'){puts 'OK'}
58
+ button = Gtk::Button.new(label:'Hello!')
59
+ window.add button
60
+ button.set_size_request 100, 50
61
+ button.signal_connect('clicked'){puts 'OK'}
62
+ ```
43
63
 
44
- To set the packing method to say, :pack_start, set the :into method as follows:
64
+ To set the packing method to say `:pack_start`, set the `:into` method as follows:
45
65
 
46
- {into: [:pack_start, expand:false, fill:false, padding:0]}
47
- # The effect in the contructor will be as if the following was run:
48
- # container.pack_start(self, expand:false, fill:false, padding:0)
66
+ ```ruby
67
+ {into: [:pack_start, expand:false, fill:false, padding:0]}
68
+ # The effect in the contructor will be as if the following was run:
69
+ # container.pack_start(self, expand:false, fill:false, padding:0)
70
+ ```
49
71
 
50
72
  One can configure Symbol keys to represent metadata about a widget:
51
73
 
74
+ ```ruby
52
75
  Thing.configure(
53
76
  KEY: [ arg1, arg2, arg3 ], # an array for super(arg1, arg2, arg3)
54
77
  key: { # a hash for like self.method(args)
@@ -58,11 +81,12 @@ One can configure Symbol keys to represent metadata about a widget:
58
81
  },
59
82
  key!: [[arg1, arg2], {meth1:args1, meth2:args2}, 'signal1', 'signal2'] # the splatter bang!
60
83
  )
84
+ ```
61
85
 
62
86
  The examples in this repository are reworks of the examples given in
63
- ZetCode.com[http://zetcode.com/gui/rubygtk/].
87
+ ZetCode.com[http://zetcode.com/gui/rubygtk/] (back in 2015).
64
88
 
65
- === Features:
89
+ ## Features:
66
90
 
67
91
  * :key! content *splat
68
92
  * Undefined :key! expanded to :KEY, :key
@@ -71,21 +95,17 @@ ZetCode.com[http://zetcode.com/gui/rubygtk/].
71
95
  * Packing method defaults (ultimately) to :add
72
96
  * Way to change default packing behaviour
73
97
 
74
- == INSTALL:
75
-
76
- $ sudo gem install such
77
-
78
- == But wait! One more thing:
98
+ ## But wait! One more thing:
79
99
 
80
- See link:examples/such_parts_demo in the examples directory
81
- and link:test/tc_part for hints on how to use the much poweful
82
- Such::Part module link:lib/such/part.rb
100
+ See [such_parts_demo](examples/such_parts_demo) in the examples directory
101
+ and [tc_part](test/tc_part) for hints on how to use the powerful
102
+ [Such::Part module](lib/such/part.rb).
83
103
 
84
- == LICENSE:
104
+ ## LICENSE:
85
105
 
86
106
  (The MIT License)
87
107
 
88
- Copyright (c) 2014
108
+ Copyright (c) 2021 CarlosJHR64
89
109
 
90
110
  Permission is hereby granted, free of charge, to any person obtaining
91
111
  a copy of this software and associated documentation files (the
data/lib/such.rb CHANGED
@@ -1,8 +1,10 @@
1
- require 'such/version'
2
- require 'such/thing'
3
- require 'such/part'
1
+ module Such
2
+ VERSION = '2.0.210201'
3
+ end
4
4
  require 'such/such'
5
+ require 'such/thing'
5
6
  require 'such/things'
7
+ require 'such/part'
6
8
  require 'such/parts'
7
9
  # Requires:
8
10
  #`ruby`
data/lib/such/part.rb CHANGED
@@ -1,29 +1,33 @@
1
1
  module Such
2
2
  module Part
3
+ PLUG_PATTERN = /^(?<sym>[^\W_]+)_(?<cls>[^\W_]+)$/
4
+
3
5
  def initialize(*parameters, &block)
4
6
  super(*parameters)
5
7
  self.class.plugs.each do |plg|
6
- if /^(?<sym>[^\W_]+)_(?<cls>[^\W_]+)$/=~plg
7
- plg, sym, cls = method("#{plg}="), "#{sym}!".to_sym, Object.const_get("Such::#{cls}")
8
- plg.call cls.new(self, sym, &block)
8
+ if md = PLUG_PATTERN.match(plg)
9
+ plg, sym, cls = "#{plg}=".to_sym, "#{md[:sym]}!".to_sym, Object.const_get("Such::#{md[:cls]}")
10
+ # self.<plg> = Such::<cls>.new(self, :<sym>!, &block)
11
+ public_send plg, cls.new(self, sym, &block)
9
12
  end
10
13
  end
11
14
  end
12
15
 
13
16
  def message(*parameters)
14
- self.class.plugs.each{|plg| method(plg).call.message(*parameters)}
17
+ self.class.plugs.each{|plg| public_send(plg).message(*parameters) }
15
18
  end
16
19
 
17
- def method_missing(plug,*args) # assuming a plug
18
- super unless args.length==0 and plug=~/^[^\W_]+_[^\W_]+$/
19
- obj = nil
20
- self.class.plugs.each do |plg|
21
- plug = method(plg).call
22
- if plug.is_a? Such::Part
23
- break if obj = plug.method(plg).call
20
+ def method_missing(maybe,*args) # maybe a plug down the plugged things.
21
+ super unless args.length==0 and PLUG_PATTERN.match?(maybe)
22
+ self.class.plugs.each do |plug|
23
+ thing = public_send(plug)
24
+ if thing.is_a? Such::Part
25
+ if obj = thing.public_send(maybe)
26
+ return obj
27
+ end
24
28
  end
25
29
  end
26
- return obj
30
+ return nil
27
31
  end
28
32
  end
29
33
  end
data/lib/such/parts.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  module Such
2
2
  module Parts
3
3
  def self.make(part, thing, *plugs)
4
- raise "Such::#{thing} not defined." unless Object.const_defined?("Such::#{thing}")
4
+ unless thing < Such::Thing and [part,*plugs].all?{_1.is_a? Symbol}
5
+ raise "Expected Such::Parts.make(Symbol part, Class thing < Such::Thing, *Symbol plugs)"
6
+ end
5
7
  plugs.each do |plug|
6
8
  if /^[^\W_]+_(?<klass>[^\W_]+)$/=~plug
7
9
  next unless $VERBOSE
@@ -12,13 +14,9 @@ module Such
12
14
  raise "Plugs must have the form key_class: #{plug}"
13
15
  end
14
16
  end
15
- Such.subclass part, thing, <<-EOT
16
- attr_accessor :#{plugs.join(', :')}
17
- def self.plugs
18
- [:#{plugs.join(', :')}]
19
- end
20
- include Such::Part
21
- EOT
17
+ subklass = Such.subclass(part, thing, include: Such::Part, attr_accessor: plugs)
18
+ subklass.singleton_class.class_eval{ define_method(:plugs){plugs} }
19
+ return subklass
22
20
  end
23
21
  end
24
22
  end
data/lib/such/such.rb CHANGED
@@ -1,9 +1,8 @@
1
1
  module Such
2
- def self.subclass(clss, sprclss="Gtk::#{clss}", body='include Such::Thing')
3
- eval <<-CODE
4
- class #{clss} < #{sprclss}
5
- #{body}
6
- end
7
- CODE
2
+ def self.subclass(name, klass, **kw, &block)
3
+ subklass = const_set(name, Class.new(klass))
4
+ kw.each{|method, args| subklass.public_send(method, *args)}
5
+ subklass.class_eval(&block) if block
6
+ return subklass
8
7
  end
9
8
  end
data/lib/such/thing.rb CHANGED
@@ -1,10 +1,14 @@
1
1
  module Such
2
2
  module Thing
3
- INTOS = [:set_submenu, :pack_start, :append, :add] # TODO:GTK!?
3
+ SIGNALS = ['clicked']
4
+ INTOS = [:set_submenu, :pack_start, :append, :add]
4
5
 
5
- PARAMETERS = {}
6
+ # PARAMETERS' pretense of being a Hash constant :P
7
+ @@PARAMETERS = {}
8
+ PARAMETERS = lambda{|k| @@PARAMETERS[k]}
9
+ def PARAMETERS.to_h = @@PARAMETERS
6
10
  def self.configure(conf)
7
- conf.each{|k,v| PARAMETERS[k]=v}
11
+ @@PARAMETERS = conf
8
12
  end
9
13
 
10
14
  def self.trace_method(obj, mthd, args)
@@ -16,8 +20,8 @@ module Such
16
20
  end
17
21
 
18
22
  def self.do_symbol(parameter, parameters)
19
- if PARAMETERS.has_key?(parameter)
20
- p = PARAMETERS[parameter]
23
+ if @@PARAMETERS.has_key?(parameter)
24
+ p = @@PARAMETERS[parameter]
21
25
  (parameter[-1]=='!')? parameters.unshift(*p) : parameters.unshift(p)
22
26
  else
23
27
  if parameter[-1]=='!'
@@ -25,7 +29,7 @@ module Such
25
29
  parameters.unshift(p.downcase.to_sym)
26
30
  parameters.unshift(p.upcase.to_sym)
27
31
  else
28
- warn "Warning: Such::PARAMETERS[#{parameter}] not defined"
32
+ warn "Warning: Such::Thing::PARAMETERS[#{parameter}] not defined"
29
33
  end
30
34
  end
31
35
  end
@@ -36,17 +40,17 @@ module Such
36
40
  case parameter
37
41
  when Symbol
38
42
  # Symbols are expected to translate to something else.
39
- Thing.do_symbol(parameter, parameters)
43
+ Thing.do_symbol parameter, parameters
40
44
  when Array
41
45
  # Arrays are added to the Thing's arguments list.
42
- arguments += parameter
46
+ arguments.concat parameter
43
47
  when Hash
44
48
  # Hashes are expected to be a symbol list of methods on Thing with respective arguments.
45
49
  # It's possible to override a previously defined method with new arguments.
46
- parameter.each{|k,v| methods[k]=v}
50
+ methods.merge! parameter
47
51
  when String
48
52
  # Typically a signal: Thing#signal_connect(signal){|*emits| block.call(*emits)}
49
- signals.push(parameter)
53
+ signals.push parameter
50
54
  else
51
55
  # Assume it's a container
52
56
  container = parameter
@@ -57,18 +61,22 @@ module Such
57
61
  end
58
62
 
59
63
  def self.which_method(container, methods=INTOS)
60
- methods.each{|mthd| return mthd if container.respond_to?(mthd)}
61
- raise "Don't know how to put into #{container.class}."
64
+ mthd = methods.detect{|m| container.respond_to?(m)}
65
+ raise "Don't know how to put into #{container.class}." if mthd.nil?
66
+ return mthd
62
67
  end
63
68
 
64
69
  def self.into(obj, container=nil, mthd=nil, *args)
65
70
  if container
66
- mthd=Thing.which_method(container) unless mthd
67
- unless mthd.class==Symbol and container.respond_to?(mthd)
68
- raise "Need container & method. Got #{container.class}##{mthd}(#{obj.class}...)"
71
+ if mthd
72
+ unless mthd.class==Symbol and container.respond_to?(mthd)
73
+ raise "Need container & method. Got #{container.class}##{mthd}(#{obj.class}...)"
74
+ end
75
+ else
76
+ mthd=Thing.which_method(container)
69
77
  end
70
78
  Thing.trace_method(container, mthd, [obj.class,*args]) if $VERBOSE
71
- container.method(mthd).call(obj, *args)
79
+ container.public_send(mthd, obj, *args)
72
80
  else
73
81
  warn "Warning: Container for #{self.class} not given."
74
82
  end
@@ -81,17 +89,14 @@ module Such
81
89
  m.call(*args)
82
90
  rescue ArgumentError, TypeError
83
91
  # Assume user meant to iterate. Note that the heuristic is not perfect.
84
- $stderr.puts "# Iterated Method #{mthd} ^^^" if $VERBOSE
92
+ $stderr.puts "# Iterated Method #{mthd}." if $VERBOSE
85
93
  [*args].each{|arg| m.call(*arg)}
86
- if $!.class == ArgumentError and not m.arity == 1
87
- warn "Warning: Iterated method's arity not one."
88
- end
89
94
  end
90
95
  end
91
96
 
92
97
  def self.do_methods(obj, methods, container=nil)
93
98
  # If user does not specify how to add to container, assume default way.
94
- methods[:into]=Thing.which_method(container) if container and !methods.has_key?(:into)
99
+ methods[:into]=Thing.which_method(container) if container and not methods.has_key?(:into)
95
100
  methods.each do |mthd, args|
96
101
  (mthd==:into)? Thing.into(obj, container, *args) :
97
102
  Thing.do_method(obj, mthd, *args)
@@ -99,16 +104,17 @@ module Such
99
104
  end
100
105
 
101
106
  def self.do_links(obj, signals, block)
107
+ return if signals.first==''
102
108
  none = (signals.length==0)
103
109
  if block
104
- signals.push('clicked') if block and none # TODO: GTK!?
110
+ signals.push(*SIGNALS) if none
105
111
  signals.each do |signal|
106
112
  break if signal==''
107
113
  begin
108
- obj.signal_connect(signal){|*emits| block.call(*emits, signal)} # TODO: GTK!?
114
+ obj.signal_connect(signal){|*emits| block.call(*emits, signal)}
109
115
  Thing.trace_signal(obj, signal) if $VERBOSE
110
116
  rescue GLib::NoSignalError
111
- warn "Warning: no \"#{signal}\" signal for #{obj.class}"
117
+ warn "Warning: no #{signal} signal for #{obj.class}"
112
118
  end
113
119
  end
114
120
  elsif not none
data/lib/such/things.rb CHANGED
@@ -1,11 +1,21 @@
1
1
  module Such
2
2
  module Things
3
- def self.list(clss=Gtk::Widget)
4
- ObjectSpace.each_object(Class).select{|k| k < clss}
3
+ def self.list(superklass)
4
+ ObjectSpace.each_object(Class).select{|klass| klass < superklass}
5
5
  end
6
6
 
7
- def self.gtk_widget
8
- Things.list.each{|clss| Such.subclass(clss.name.sub('Gtk::',''))}
7
+ def self.subclass(klass)
8
+ Such.subclass(klass.name.sub(/^.*::/,'').to_sym, klass, include: Such::Thing)
9
+ end
10
+
11
+ def self.in(superklass)
12
+ Things.list(superklass).each do |klass|
13
+ begin
14
+ Things.subclass(klass)
15
+ rescue
16
+ $stderr.puts "#{$!.class}:\t#{superklass}" if $VERBOSE
17
+ end
18
+ end
9
19
  end
10
20
  end
11
21
  end
metadata CHANGED
@@ -1,43 +1,38 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: such
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 2.0.210201
5
5
  platform: ruby
6
6
  authors:
7
7
  - carlosjhr64
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-24 00:00:00.000000000 Z
11
+ date: 2021-02-01 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
- Wraps Ruby's Gtk widgets with an alternate constructor
14
+ Wraps widgets with an alternate constructor
15
15
  which factors out the configuration and assembly procedures into metadata.
16
-
17
- And the _Such_ module can be used to wrap any class with the alternate constructor,
18
- although currently only _Gtk3_ widgets is supported.
16
+ Can be used to wrap any class with the alternate constructor,
17
+ although targeted only Gtk3 widgets.
19
18
  email: carlosjhr64@gmail.com
20
19
  executables: []
21
20
  extensions: []
22
- extra_rdoc_files:
23
- - README.rdoc
21
+ extra_rdoc_files: []
24
22
  files:
25
- - README.rdoc
23
+ - README.md
26
24
  - lib/such.rb
27
25
  - lib/such/part.rb
28
26
  - lib/such/parts.rb
29
27
  - lib/such/such.rb
30
28
  - lib/such/thing.rb
31
29
  - lib/such/things.rb
32
- - lib/such/version.rb
33
30
  homepage: https://github.com/carlosjhr64/such
34
31
  licenses:
35
32
  - MIT
36
33
  metadata: {}
37
- post_install_message:
38
- rdoc_options:
39
- - "--main"
40
- - README.rdoc
34
+ post_install_message:
35
+ rdoc_options: []
41
36
  require_paths:
42
37
  - lib
43
38
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -51,12 +46,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
51
46
  - !ruby/object:Gem::Version
52
47
  version: '0'
53
48
  requirements:
54
- - 'ruby: ruby 2.1.3p242 (2014-09-19 revision 47630) [x86_64-linux]'
55
- rubyforge_project:
56
- rubygems_version: 2.4.1
57
- signing_key:
49
+ - 'ruby: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-linux]'
50
+ rubygems_version: 3.2.3
51
+ signing_key:
58
52
  specification_version: 4
59
- summary: Wraps Ruby's Gtk widgets with an alternate constructor which factors out
60
- the configuration and assembly procedures into metadata.
53
+ summary: Wraps widgets with an alternate constructor which factors out the configuration
54
+ and assembly procedures into metadata. Can be used to wrap any class with the alternate
55
+ constructor, although targeted only Gtk3 widgets.
61
56
  test_files: []
62
- has_rdoc:
data/lib/such/version.rb DELETED
@@ -1,3 +0,0 @@
1
- module Such
2
- VERSION = '0.2.0'
3
- end