such 0.2.0 → 2.0.210201

Sign up to get free protection for your applications and to get access to all the features.
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