markdown_exec 2.0.8.4 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/menu.src.yml CHANGED
@@ -127,6 +127,13 @@
127
127
  :opt_name: menu_for_saved_lines
128
128
  :procname: val_as_bool
129
129
 
130
+ - :arg_name: BOOL
131
+ :default: true
132
+ :description: Add menu options for history
133
+ :env_var: MDE_menu_for_history
134
+ :opt_name: menu_for_history
135
+ :procname: val_as_bool
136
+
130
137
  - :arg_name: BOOL
131
138
  :default: false
132
139
  :description: Dump @delegate_object
@@ -268,8 +275,10 @@
268
275
  :default: false
269
276
  :description: Execute script in own window
270
277
  :env_var: MDE_EXECUTE_IN_OWN_WINDOW
278
+ :long_name: execute_in_own_window
271
279
  :opt_name: execute_in_own_window
272
280
  :procname: val_as_bool
281
+ :short_name: w
273
282
 
274
283
  - :default: fg_rgbh_7f_ff_00
275
284
  :description: execution_report_preview_frame_color
@@ -296,13 +305,13 @@
296
305
 
297
306
  ## match fenced code indented by spaces
298
307
  #
299
- - :default: "^(?<indent> *)`{3,}"
308
+ - :default: "^(?<indent>[ \t]*)`{3,}"
300
309
  :description: Matches the start and end of a fenced code block
301
310
  :env_var: MDE_FENCED_START_AND_END_REGEX
302
311
  :opt_name: fenced_start_and_end_regex
303
312
  :procname: val_as_str
304
313
 
305
- - :default: "^(?<indent> *)`{3,}(?<shell>[^`\\s]*) *(:(?<name>[^\\s]*))? *(?<rest>.*) *$"
314
+ - :default: "^(?<indent>[ \t]*)`{3,}(?<shell>[^`\\s]*) *(:(?<name>[^\\s]*))? *(?<rest>.*) *$"
306
315
  :description: Match the start of a fenced block
307
316
  :env_var: MDE_FENCED_START_EXTENDED_REGEX
308
317
  :opt_name: fenced_start_extended_regex
@@ -373,7 +382,7 @@
373
382
 
374
383
  - :arg_name: HOW
375
384
  :default: ''
376
- :description: Find in YAML configuration options
385
+ :description: Find keyword in YAML configuration options
377
386
  :long_name: how
378
387
  :procname: how
379
388
  :short_name: "?"
@@ -431,6 +440,7 @@
431
440
  :long_name: load-code
432
441
  :opt_name: load_code
433
442
  :procname: val_as_str
443
+ :short_name: l
434
444
 
435
445
  - :arg_name: PREFIX
436
446
  :default: mde
@@ -500,7 +510,7 @@
500
510
  :opt_name: menu_divider_format
501
511
  :procname: val_as_str
502
512
 
503
- - :default: "^:::(?<line>(?<indent>[ \t]*)(?<text>.*?)(?<trailing>[ \t]*))?$"
513
+ - :default: "^(?<indent>[ \t]*):::(?<line>(?<text>.*?)(?<trailing>[ \t]*))?$"
504
514
  :description: Pattern for topics/dividers in block selection menu
505
515
  :env_var: MDE_MENU_DIVIDER_MATCH
506
516
  :opt_name: menu_divider_match
@@ -643,8 +653,9 @@
643
653
  :opt_name: menu_note_format
644
654
  :procname: val_as_str
645
655
 
646
- ## all lines that do not start with "/ " are notes
647
- - :default: "^(?<line>(?!/ )(?<indent>[ \t]*)(?<text>.*?)(?<trailing>[ \t]*))?$"
656
+ ## lines that start with "/" are comments (hidden), not notes (visible)
657
+ # - :default: "^(?<indent>[ \t]*)(?<line>(?!/)(?<text>.*?)(?<trailing>[ \t]*))?$"
658
+ - :default: "^(?<line>(?![ \t]*/)(?<text>.*?)(?<trailing>[ \t]*))?$"
648
659
  :description: Pattern for notes in block selection menu
649
660
  :env_var: MDE_MENU_NOTE_MATCH
650
661
  :opt_name: menu_note_match
@@ -671,6 +682,13 @@
671
682
  :opt_name: menu_option_exit_name
672
683
  :procname: val_as_str
673
684
 
685
+ - :default:
686
+ :line: "* History"
687
+ :description: Text for History option
688
+ :env_var: MDE_MENU_OPTION_HISTORY_NAME
689
+ :opt_name: menu_option_history_name
690
+ :procname: val_as_str
691
+
674
692
  - :default:
675
693
  :line: "* Load"
676
694
  :description: Text for Load option
@@ -951,13 +969,19 @@
951
969
  :procname: val_as_str
952
970
 
953
971
  - :default: Back
954
- :description: Quit prompt
955
- :env_var: MDE_PROMPT_FILESPEC_OTHER
972
+ :description: User wants out of menu
973
+ :env_var: MDE_PROMPT_FILESPEC_BACK
956
974
  :opt_name: prompt_filespec_back
957
975
  :procname: val_as_str
958
976
 
977
+ - :default: Facet
978
+ :description: User wants to tailor the menu
979
+ :env_var: MDE_PROMPT_FILESPEC_FACET
980
+ :opt_name: prompt_filespec_facet
981
+ :procname: val_as_str
982
+
959
983
  - :default: Other
960
- :description: Prompt for a custom file name
984
+ :description: User wants a custom file name
961
985
  :env_var: MDE_PROMPT_FILESPEC_OTHER
962
986
  :opt_name: prompt_filespec_other
963
987
  :procname: val_as_str
@@ -992,6 +1016,12 @@
992
1016
  :opt_name: prompt_select_code_file
993
1017
  :procname: val_as_str
994
1018
 
1019
+ - :default: "\nView file:"
1020
+ :description: Prompt to select a saved asset
1021
+ :env_var: MDE_PROMPT_SELECT_HISTORY_FILE
1022
+ :opt_name: prompt_select_history_file
1023
+ :procname: val_as_str
1024
+
995
1025
  - :default: "\nChoose a file:"
996
1026
  :description: Prompt to select a markdown document
997
1027
  :env_var: MDE_PROMPT_SELECT_MD
@@ -1022,7 +1052,7 @@
1022
1052
  :opt_name: prompt_yes
1023
1053
  :procname: val_as_str
1024
1054
 
1025
- - :description: Gem home folder
1055
+ - :description: Print the gem's home directory
1026
1056
  :long_name: pwd
1027
1057
  :opt_name: pwd
1028
1058
  :procname: val_as_bool
@@ -1038,6 +1068,18 @@
1038
1068
  :opt_name: runtime_exception_error_level
1039
1069
  :procname: val_as_int
1040
1070
 
1071
+ - :default: '%{prefix}%{join}%{time}%{join}%{filename}%{join}%{mark}%{join}%{blockname}%{join}%{exts}'
1072
+ :description: Format for script and log file names
1073
+ :env_var: MDE_SAVED_ASSET_FORMAT
1074
+ :opt_name: saved_asset_format
1075
+ :procname: val_as_str
1076
+
1077
+ - :default: "^(?<prefix>.+)(?<join>_)(?<time>[0-9\\-]+)\\g'join'(?<filename>.+)\\g'join'(?<mark>~)\\g'join'(?<blockname>.+)\\g'join'(?<exts>\\..+)$"
1078
+ :description: Regexp for script and log file names
1079
+ :env_var: MDE_SAVED_ASSET_MATCH
1080
+ :opt_name: saved_asset_match
1081
+ :procname: val_as_str
1082
+
1041
1083
  - :arg_name: BOOL
1042
1084
  :default: false
1043
1085
  :description: Whether to save an executed script
@@ -1064,6 +1106,12 @@
1064
1106
  :opt_name: saved_filename_replacement
1065
1107
  :procname: val_as_str
1066
1108
 
1109
+ - :default: '%{time} %{blockname} %{exts}'
1110
+ :description: Format for each row displayed in history
1111
+ :env_var: MDE_SAVED_HISTORY_FORMAT
1112
+ :opt_name: saved_history_format
1113
+ :procname: val_as_str
1114
+
1067
1115
  - :arg_name: INT
1068
1116
  :default: 493
1069
1117
  :description: chmod for saved scripts
@@ -1162,16 +1210,6 @@
1162
1210
  :opt_name: select_page_height
1163
1211
  :procname: val_as_int
1164
1212
 
1165
- - :description: Select and execute a recently saved output
1166
- :long_name: select-recent-output
1167
- :opt_name: select_recent_output
1168
- :procname: val_as_bool
1169
-
1170
- - :description: Select and execute a recently saved script
1171
- :long_name: select-recent-script
1172
- :opt_name: select_recent_script
1173
- :procname: val_as_bool
1174
-
1175
1213
  - :default: "#!/usr/bin/env"
1176
1214
  :description: Shebang for saved scripts
1177
1215
  :env_var: MDE_SHEBANG
@@ -1202,6 +1240,13 @@
1202
1240
  :opt_name: shell_code_label_time_format
1203
1241
  :procname: val_as_str
1204
1242
 
1243
+ - :arg_name: BOOL
1244
+ :default: true
1245
+ :description: Whether saved file names include shell parameter expansion
1246
+ :env_var: MDE_SHELL_PARAMETER_EXPANSION
1247
+ :opt_name: shell_parameter_expansion
1248
+ :procname: val_as_bool
1249
+
1205
1250
  - :description: List tab completions
1206
1251
  :long_name: tab-completions
1207
1252
  :opt_name: tab_completions
data/lib/menu.yml CHANGED
@@ -106,6 +106,12 @@
106
106
  :env_var: MDE_MENU_FOR_SAVED_LINES
107
107
  :opt_name: menu_for_saved_lines
108
108
  :procname: val_as_bool
109
+ - :arg_name: BOOL
110
+ :default: true
111
+ :description: Add menu options for history
112
+ :env_var: MDE_menu_for_history
113
+ :opt_name: menu_for_history
114
+ :procname: val_as_bool
109
115
  - :arg_name: BOOL
110
116
  :default: false
111
117
  :description: Dump @delegate_object
@@ -230,8 +236,10 @@
230
236
  :default: false
231
237
  :description: Execute script in own window
232
238
  :env_var: MDE_EXECUTE_IN_OWN_WINDOW
239
+ :long_name: execute_in_own_window
233
240
  :opt_name: execute_in_own_window
234
241
  :procname: val_as_bool
242
+ :short_name: w
235
243
  - :default: fg_rgbh_7f_ff_00
236
244
  :description: execution_report_preview_frame_color
237
245
  :env_var: MDE_EXECUTION_REPORT_PREVIEW_FRAME_COLOR
@@ -253,12 +261,12 @@
253
261
  :long_name: exit
254
262
  :procname: exit
255
263
  :short_name: x
256
- - :default: "^(?<indent> *)`{3,}"
264
+ - :default: "^(?<indent>[ \t]*)`{3,}"
257
265
  :description: Matches the start and end of a fenced code block
258
266
  :env_var: MDE_FENCED_START_AND_END_REGEX
259
267
  :opt_name: fenced_start_and_end_regex
260
268
  :procname: val_as_str
261
- - :default: "^(?<indent> *)`{3,}(?<shell>[^`\\s]*) *(:(?<name>[^\\s]*))? *(?<rest>.*)
269
+ - :default: "^(?<indent>[ \t]*)`{3,}(?<shell>[^`\\s]*) *(:(?<name>[^\\s]*))? *(?<rest>.*)
262
270
  *$"
263
271
  :description: Match the start of a fenced block
264
272
  :env_var: MDE_FENCED_START_EXTENDED_REGEX
@@ -319,7 +327,7 @@
319
327
  :procname: val_as_str
320
328
  - :arg_name: HOW
321
329
  :default: ''
322
- :description: Find in YAML configuration options
330
+ :description: Find keyword in YAML configuration options
323
331
  :long_name: how
324
332
  :procname: how
325
333
  :short_name: "?"
@@ -367,6 +375,7 @@
367
375
  :long_name: load-code
368
376
  :opt_name: load_code
369
377
  :procname: val_as_str
378
+ :short_name: l
370
379
  - :arg_name: PREFIX
371
380
  :default: mde
372
381
  :description: Name prefix for stdout files
@@ -425,7 +434,7 @@
425
434
  :env_var: MDE_MENU_DIVIDER_FORMAT
426
435
  :opt_name: menu_divider_format
427
436
  :procname: val_as_str
428
- - :default: "^:::(?<line>(?<indent>[ \t]*)(?<text>.*?)(?<trailing>[ \t]*))?$"
437
+ - :default: "^(?<indent>[ \t]*):::(?<line>(?<text>.*?)(?<trailing>[ \t]*))?$"
429
438
  :description: Pattern for topics/dividers in block selection menu
430
439
  :env_var: MDE_MENU_DIVIDER_MATCH
431
440
  :opt_name: menu_divider_match
@@ -542,7 +551,7 @@
542
551
  :env_var: MDE_MENU_NOTE_FORMAT
543
552
  :opt_name: menu_note_format
544
553
  :procname: val_as_str
545
- - :default: "^(?<line>(?!/ )(?<indent>[ \t]*)(?<text>.*?)(?<trailing>[ \t]*))?$"
554
+ - :default: "^(?<line>(?![ \t]*/)(?<text>.*?)(?<trailing>[ \t]*))?$"
546
555
  :description: Pattern for notes in block selection menu
547
556
  :env_var: MDE_MENU_NOTE_MATCH
548
557
  :opt_name: menu_note_match
@@ -565,6 +574,12 @@
565
574
  :env_var: MDE_MENU_OPTION_EXIT_NAME
566
575
  :opt_name: menu_option_exit_name
567
576
  :procname: val_as_str
577
+ - :default:
578
+ :line: "* History"
579
+ :description: Text for History option
580
+ :env_var: MDE_MENU_OPTION_HISTORY_NAME
581
+ :opt_name: menu_option_history_name
582
+ :procname: val_as_str
568
583
  - :default:
569
584
  :line: "* Load"
570
585
  :description: Text for Load option
@@ -808,12 +823,17 @@
808
823
  :opt_name: prompt_exit
809
824
  :procname: val_as_str
810
825
  - :default: Back
811
- :description: Quit prompt
812
- :env_var: MDE_PROMPT_FILESPEC_OTHER
826
+ :description: User wants out of menu
827
+ :env_var: MDE_PROMPT_FILESPEC_BACK
813
828
  :opt_name: prompt_filespec_back
814
829
  :procname: val_as_str
830
+ - :default: Facet
831
+ :description: User wants to tailor the menu
832
+ :env_var: MDE_PROMPT_FILESPEC_FACET
833
+ :opt_name: prompt_filespec_facet
834
+ :procname: val_as_str
815
835
  - :default: Other
816
- :description: Prompt for a custom file name
836
+ :description: User wants a custom file name
817
837
  :env_var: MDE_PROMPT_FILESPEC_OTHER
818
838
  :opt_name: prompt_filespec_other
819
839
  :procname: val_as_str
@@ -848,6 +868,13 @@
848
868
  :procname: val_as_str
849
869
  - :default: |2-
850
870
 
871
+ View file:
872
+ :description: Prompt to select a saved asset
873
+ :env_var: MDE_PROMPT_SELECT_HISTORY_FILE
874
+ :opt_name: prompt_select_history_file
875
+ :procname: val_as_str
876
+ - :default: |2-
877
+
851
878
  Choose a file:
852
879
  :description: Prompt to select a markdown document
853
880
  :env_var: MDE_PROMPT_SELECT_MD
@@ -875,7 +902,7 @@
875
902
  :env_var: MDE_PROMPT_YES
876
903
  :opt_name: prompt_yes
877
904
  :procname: val_as_str
878
- - :description: Gem home folder
905
+ - :description: Print the gem's home directory
879
906
  :long_name: pwd
880
907
  :opt_name: pwd
881
908
  :procname: val_as_bool
@@ -889,6 +916,16 @@
889
916
  :env_var: MDE_RUNTIME_EXCEPTION_ERROR_LEVEL
890
917
  :opt_name: runtime_exception_error_level
891
918
  :procname: val_as_int
919
+ - :default: "%{prefix}%{join}%{time}%{join}%{filename}%{join}%{mark}%{join}%{blockname}%{join}%{exts}"
920
+ :description: Format for script and log file names
921
+ :env_var: MDE_SAVED_ASSET_FORMAT
922
+ :opt_name: saved_asset_format
923
+ :procname: val_as_str
924
+ - :default: "^(?<prefix>.+)(?<join>_)(?<time>[0-9\\-]+)\\g'join'(?<filename>.+)\\g'join'(?<mark>~)\\g'join'(?<blockname>.+)\\g'join'(?<exts>\\..+)$"
925
+ :description: Regexp for script and log file names
926
+ :env_var: MDE_SAVED_ASSET_MATCH
927
+ :opt_name: saved_asset_match
928
+ :procname: val_as_str
892
929
  - :arg_name: BOOL
893
930
  :default: false
894
931
  :description: Whether to save an executed script
@@ -911,6 +948,11 @@
911
948
  :env_var: MDE_SAVED_FILENAME_REPLACEMENT
912
949
  :opt_name: saved_filename_replacement
913
950
  :procname: val_as_str
951
+ - :default: "%{time} %{blockname} %{exts}"
952
+ :description: Format for each row displayed in history
953
+ :env_var: MDE_SAVED_HISTORY_FORMAT
954
+ :opt_name: saved_history_format
955
+ :procname: val_as_str
914
956
  - :arg_name: INT
915
957
  :default: 493
916
958
  :description: chmod for saved scripts
@@ -998,14 +1040,6 @@
998
1040
  :env_var: MDE_SELECT_PAGE_HEIGHT
999
1041
  :opt_name: select_page_height
1000
1042
  :procname: val_as_int
1001
- - :description: Select and execute a recently saved output
1002
- :long_name: select-recent-output
1003
- :opt_name: select_recent_output
1004
- :procname: val_as_bool
1005
- - :description: Select and execute a recently saved script
1006
- :long_name: select-recent-script
1007
- :opt_name: select_recent_script
1008
- :procname: val_as_bool
1009
1043
  - :default: "#!/usr/bin/env"
1010
1044
  :description: Shebang for saved scripts
1011
1045
  :env_var: MDE_SHEBANG
@@ -1032,6 +1066,12 @@
1032
1066
  :env_var: MDE_SHELL_CODE_LABEL_TIME_FORMAT
1033
1067
  :opt_name: shell_code_label_time_format
1034
1068
  :procname: val_as_str
1069
+ - :arg_name: BOOL
1070
+ :default: true
1071
+ :description: Whether saved file names include shell parameter expansion
1072
+ :env_var: MDE_SHELL_PARAMETER_EXPANSION
1073
+ :opt_name: shell_parameter_expansion
1074
+ :procname: val_as_bool
1035
1075
  - :description: List tab completions
1036
1076
  :long_name: tab-completions
1037
1077
  :opt_name: tab_completions
data/lib/namer.rb ADDED
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # encoding=utf-8
5
+ require 'digest'
6
+ # require_relative 'poly'
7
+
8
+ $pd = false unless defined?($pd)
9
+
10
+ class Hash
11
+ # block name in commands and documents
12
+ def pub_name(**kwargs)
13
+ full = fetch(:nickname, nil) || fetch(:oname, nil)
14
+ full&.to_s&.pub_name(**kwargs).tap { |ret| pp [__LINE__, 'Hash.pub_name() ->', ret] if $pd }
15
+ end
16
+ end
17
+
18
+ class String
19
+ FN_ID_LEN = 4
20
+ FN_MAX_LEN = 64
21
+ FN_PATTERN = %r{[^!#%\+\-0-9=@A-Z_a-z()\[\]{}]}.freeze # characters than can be used in a file name without quotes or escaping
22
+ # except '.', ',', '~' reserved for tokenization
23
+ # / !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
24
+ FN_REPLACEMENT = '_'
25
+
26
+ # block name in commands and documents
27
+ def pub_name(
28
+ id_len: FN_ID_LEN, max_len: FN_MAX_LEN,
29
+ pattern: FN_PATTERN, replacement: FN_REPLACEMENT
30
+ )
31
+ trimmed = if self[max_len]
32
+ rand(((10**(id_len - 1)) + 1)..(10**id_len)).to_s
33
+ dig = Digest::MD5.hexdigest(self)[0, id_len]
34
+ self[0..max_len - id_len] + dig
35
+ else
36
+ self
37
+ end
38
+
39
+ trimmed.gsub(pattern, replacement).tap { |ret| pp [__LINE__, 'String.pub_name() ->', ret] if $pd }
40
+ end
41
+ end
42
+
43
+ # require 'ostruct'
44
+
45
+ # class BlkS < OpenStruct
46
+ # # Method to fetch the value associated with the attribute :nickname or :oname
47
+ # def pub_name
48
+ # self.nickname || self.oname
49
+ # end
50
+ # end
data/lib/poly.rb ADDED
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # encoding=utf-8
5
+
6
+ $pd = false
7
+
8
+ class Poly
9
+ # attr_reader :table
10
+ def initialize(table = {})
11
+ @table = table.tap{|ret| pp [__LINE__,'Poly.initialize()','table',table.to_yaml] if $pd }
12
+ end
13
+
14
+ def fetch(key, *args)
15
+ key_sym = key.to_sym
16
+ if respond_to?("get_#{key}")
17
+ send("get_#{key}")
18
+ elsif @table.key?(key_sym)
19
+ @table[key_sym]
20
+ elsif block_given?
21
+ yield key_sym
22
+ elsif args.count.positive?
23
+ # binding.irb
24
+ args.first
25
+ else
26
+ binding.irb
27
+ raise KeyError, "key not found: #{key}"
28
+ end.tap{|ret| pp([__LINE__,"Poly.fetch #{key} #{args}",'->',ret]) if $pd }
29
+ end
30
+
31
+ def key?(name)
32
+ @table.key?(name.to_sym).tap{|ret| pp([__LINE__,"Poly.key? #{name}",'->',ret]) if $pd }
33
+ end
34
+
35
+ def method_missing(name, *args)
36
+ pt = nil
37
+ if name.to_s.end_with?('=')
38
+ # Setter method
39
+ attribute = name.to_s.chomp('=').to_sym
40
+ value = args.first
41
+ if respond_to?("set_#{attribute}")
42
+ pt = 'send set_'
43
+ send("set_#{attribute}", value)
44
+ else
45
+ pt = 'table set'
46
+ @table[attribute] = value
47
+ end
48
+ elsif respond_to?("get_#{name}")
49
+ pt = 'send get_'
50
+ # Getter method
51
+ send("get_#{name}")
52
+ elsif @table.respond_to?(name)
53
+ pt = 'send name'
54
+ @table.send(name, *args)
55
+ else
56
+ pt = 'table read'
57
+ @table[name.to_sym]
58
+ end.tap{|ret| pp([__LINE__,"Poly.method_missing #{name} #{args.map(&:to_s).join(' ')}",pt,'->',ret]) if $pd }
59
+ end
60
+
61
+ def respond_to_missing?(name, include_private = false)
62
+ # name.to_s.end_with?('=') || @table.key?(name.to_sym) || @table.respond_to?(name) || super
63
+ (name.to_s.end_with?('=') || @table.key?(name.to_sym) || @table.respond_to?(name) || super).tap{|ret| pp([__LINE__,"Poly.respond_to_missing? #{name}",'->',ret]) if $pd }
64
+ end
65
+
66
+ def [](key)
67
+ if respond_to?("get_#{key}")
68
+ send("get_#{key}")
69
+ else
70
+ @table[key.to_sym]
71
+ end.tap{|ret| pp([__LINE__,"Poly.[] #{key}",'->',ret]) if $pd }
72
+ end
73
+
74
+ def []=(key, value)
75
+ if respond_to?("set_#{key}")
76
+ send("set_#{key}", value)
77
+ else
78
+ @table[key.to_sym] = value
79
+ end.tap{|ret| pp([__LINE__,"Poly.[]= #{key} #{value}",'->',ret]) if $pd }
80
+ end
81
+
82
+ # for export to Prompt library
83
+ # def merge(*args)
84
+ # Proc.new { |x| @table.merge x }
85
+ # end
86
+ def merge(*args)
87
+ # pp caller
88
+ # binding.irb
89
+ @table.merge(*args).tap{|ret| pp([__LINE__,"Poly.merge",'->',ret]) if $pd }
90
+ end
91
+
92
+ # for export to Prompt library
93
+ def to_h
94
+ @table.tap{|ret| pp([__LINE__,"Poly.to_h",'->',ret]) if $pd }
95
+ end
96
+
97
+ def to_yaml
98
+ @table.to_yaml.tap{|ret| pp([__LINE__,"Poly.to_yaml",'->',ret]) if $pd }
99
+ end
100
+ end
101
+
102
+ # class CustomStruct < Poly
103
+ # # Custom setter for virtual attribute :full_name
104
+ # def set_full_name(value)
105
+ # names = value.split(' ')
106
+ # @table[:first_name] = names.first
107
+ # @table[:last_name] = names.last
108
+ # end
109
+
110
+ # # Custom getter for virtual attribute :full_name
111
+ # def get_full_name
112
+ # "#{@table[:first_name]} #{@table[:last_name]}"
113
+ # end
114
+ # end
115
+
116
+ # # Example usage
117
+ # person = CustomStruct.new
118
+ # person.first_name = 'John'
119
+ # person.last_name = 'Doe'
120
+ # puts person.first_name # => John
121
+ # puts person.last_name # => Doe
122
+
123
+ # # Setting and getting a virtual attribute
124
+ # person.full_name = 'Jane Smith'
125
+ # puts person.first_name # => Jane
126
+ # puts person.last_name # => Smith
127
+ # puts person.full_name # => Jane Smith
128
+
129
+ # # Setting and getting a regular attribute
130
+ # person.age = 30
131
+ # puts person.age # => 30
132
+
133
+ # # Using array notation
134
+ # person[:age] = 35
135
+ # puts person[:age] # => 35
136
+
137
+ # person[:full_name] = 'Alice Johnson'
138
+ # puts person[:first_name] # => Alice
139
+ # puts person[:last_name] # => Johnson
140
+ # puts person[:full_name] # => Alice Johnson
141
+
142
+ # # Using fetch method
143
+ # puts person.fetch(:age) # => 35
144
+ # puts person.fetch(:nonexistent, 'default') # => default
145
+ # puts person.fetch(:nonexistent) { |key| "block default for #{key}" } # => block default for nonexistent
146
+
147
+ # # This will raise a KeyError
148
+ # begin
149
+ # person.fetch(:nonexistent)
150
+ # rescue KeyError => e
151
+ # puts e.message # => key not found: nonexistent
152
+ # end