such 0.1.0 → 1.0.210117

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: 273d09f4d688a045d6a70dd875eb512b2241de79
4
- data.tar.gz: 09d23e4dfb1159e745dfe4a36df55de114e44e90
2
+ SHA256:
3
+ metadata.gz: 8455f46116268e25b466323fb8d75b76d6084c815b8007a5d7d8cd934a15758d
4
+ data.tar.gz: 577f05b1c0bc9d4d3a1a93ee58103f7656243dbd064ed7d887cec899a3de47e6
5
5
  SHA512:
6
- metadata.gz: eb329b8288a37f2a788fd9992e0235b2b261e305f1f9320413af205b602ec00fb8d52fdf2dd52969ed604154849272eeb79965b0b3426e0c656874314cd08a4d
7
- data.tar.gz: 643ef446c8492324a1863c86ad4ad0724926d32370ec3af73e60b675131233e03dcaebd9ebd854a12343a19195c513683f62c4ba1c491b284aaf9e60b2346774
6
+ metadata.gz: c008f4588f1ea74638d76279d0f7ccc9ffd1a9f321e2cbd32d14bf0ad5e7da70903995b03d9820cf4a95af302269b5d99c9bf952fa7a346aebc77724d9091ddf
7
+ data.tar.gz: 8cce6a2ce219fe0f9a435f9d4236cb24ba28d60e62b585eb53cd2aa49bb9aacdf5ae43d29a864c761d472ded4cd02a3dca989c3a24b19dd8b5bc40658e303417
@@ -1,54 +1,77 @@
1
- = Such
1
+ # Such
2
2
 
3
- == DESCRIPTION:
3
+ * [VERSION 1.0.210117](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
@@ -1,8 +1,10 @@
1
- require 'such/version'
2
- require 'such/thing'
3
- require 'such/part'
1
+ module Such
2
+ VERSION = '1.0.210117'
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`
@@ -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
@@ -1,17 +1,22 @@
1
1
  module Such
2
2
  module Parts
3
3
  def self.make(part, thing, *plugs)
4
- raise "Superclass(#{thing}) must be a Such::Thing" unless Object.const_get(thing) < Such::Thing
5
- plugs.each{|plug|
6
- raise "Plugs must have the form key_class: #{plug}" unless plug=~/^[^\W_]+_[^\W_]+$/
7
- }
8
- Such.subclass part, thing, <<-EOT
9
- attr_accessor :#{plugs.join(', :')}
10
- def self.plugs
11
- [:#{plugs.join(', :')}]
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
7
+ plugs.each do |plug|
8
+ if /^[^\W_]+_(?<klass>[^\W_]+)$/=~plug
9
+ next unless $VERBOSE
10
+ unless Object.const_defined?("Such::#{klass}")
11
+ $stderr.puts "Warning: Such::#{klass} not defined yet."
12
+ end
13
+ else
14
+ raise "Plugs must have the form key_class: #{plug}"
12
15
  end
13
- include Such::Part
14
- EOT
16
+ end
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
15
20
  end
16
21
  end
17
22
  end
@@ -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
@@ -1,10 +1,11 @@
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
6
  PARAMETERS = {}
6
7
  def self.configure(conf)
7
- conf.each{|k,v| PARAMETERS[k]=v}
8
+ PARAMETERS.merge! conf
8
9
  end
9
10
 
10
11
  def self.trace_method(obj, mthd, args)
@@ -25,7 +26,7 @@ module Such
25
26
  parameters.unshift(p.downcase.to_sym)
26
27
  parameters.unshift(p.upcase.to_sym)
27
28
  else
28
- warn "Warning: Such::PARAMETERS[#{parameter}] not defined"
29
+ warn "Warning: Such::Thing::PARAMETERS[#{parameter}] not defined"
29
30
  end
30
31
  end
31
32
  end
@@ -36,17 +37,17 @@ module Such
36
37
  case parameter
37
38
  when Symbol
38
39
  # Symbols are expected to translate to something else.
39
- Thing.do_symbol(parameter, parameters)
40
+ Thing.do_symbol parameter, parameters
40
41
  when Array
41
42
  # Arrays are added to the Thing's arguments list.
42
- arguments += parameter
43
+ arguments.concat parameter
43
44
  when Hash
44
45
  # Hashes are expected to be a symbol list of methods on Thing with respective arguments.
45
46
  # It's possible to override a previously defined method with new arguments.
46
- parameter.each{|k,v| methods[k]=v}
47
+ methods.merge! parameter
47
48
  when String
48
49
  # Typically a signal: Thing#signal_connect(signal){|*emits| block.call(*emits)}
49
- signals.push(parameter)
50
+ signals.push parameter
50
51
  else
51
52
  # Assume it's a container
52
53
  container = parameter
@@ -57,18 +58,22 @@ module Such
57
58
  end
58
59
 
59
60
  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}."
61
+ mthd = methods.detect{|m| container.respond_to?(m)}
62
+ raise "Don't know how to put into #{container.class}." if mthd.nil?
63
+ return mthd
62
64
  end
63
65
 
64
66
  def self.into(obj, container=nil, mthd=nil, *args)
65
67
  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}...)"
68
+ if mthd
69
+ unless mthd.class==Symbol and container.respond_to?(mthd)
70
+ raise "Need container & method. Got #{container.class}##{mthd}(#{obj.class}...)"
71
+ end
72
+ else
73
+ mthd=Thing.which_method(container)
69
74
  end
70
75
  Thing.trace_method(container, mthd, [obj.class,*args]) if $VERBOSE
71
- container.method(mthd).call(obj, *args)
76
+ container.public_send(mthd, obj, *args)
72
77
  else
73
78
  warn "Warning: Container for #{self.class} not given."
74
79
  end
@@ -81,17 +86,14 @@ module Such
81
86
  m.call(*args)
82
87
  rescue ArgumentError, TypeError
83
88
  # Assume user meant to iterate. Note that the heuristic is not perfect.
84
- $stderr.puts "# Iterated Method #{mthd} ^^^" if $VERBOSE
89
+ $stderr.puts "# Iterated Method #{mthd}." if $VERBOSE
85
90
  [*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
91
  end
90
92
  end
91
93
 
92
94
  def self.do_methods(obj, methods, container=nil)
93
95
  # 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)
96
+ methods[:into]=Thing.which_method(container) if container and not methods.has_key?(:into)
95
97
  methods.each do |mthd, args|
96
98
  (mthd==:into)? Thing.into(obj, container, *args) :
97
99
  Thing.do_method(obj, mthd, *args)
@@ -99,16 +101,17 @@ module Such
99
101
  end
100
102
 
101
103
  def self.do_links(obj, signals, block)
104
+ return if signals.first==''
102
105
  none = (signals.length==0)
103
106
  if block
104
- signals.push('clicked') if block and none # TODO: GTK!?
107
+ signals.push(*SIGNALS) if none
105
108
  signals.each do |signal|
106
109
  break if signal==''
107
110
  begin
108
- obj.signal_connect(signal){|*emits| block.call(*emits, signal)} # TODO: GTK!?
111
+ obj.signal_connect(signal){|*emits| block.call(*emits, signal)}
109
112
  Thing.trace_signal(obj, signal) if $VERBOSE
110
113
  rescue GLib::NoSignalError
111
- warn "Warning: no \"#{signal}\" signal for #{obj.class}"
114
+ warn "Warning: no #{signal} signal for #{obj.class}"
112
115
  end
113
116
  end
114
117
  elsif not none
@@ -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.1.0
4
+ version: 1.0.210117
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-15 00:00:00.000000000 Z
11
+ date: 2021-01-17 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:
@@ -1,3 +0,0 @@
1
- module Such
2
- VERSION = '0.1.0'
3
- end