such 0.1.0 → 1.0.210117

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: 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