module RubymentExperimentModule
# begin_documentation This module receives functions that are being worked on. # end_documentation
Public Instance Methods
# documentation_begin # short_desc => “calls the method call of an object, or return the object itself”, @memory.push = {
:function => :call_or_itself, :short_desc => short_desc, :description => "", :params => [ { :name => :args, :description => "list of parameters", :duck_type => Array, :default_behavior => [], :params => [ { :name => :object, :duck_type => Object, :default_behavior => :nil, :description => "object to be called, if responds to #call, or to return itself", }, { :name => :return_dont_call, :duck_type => Object, :default_behavior => :nil, :description => "forces an object to return itself even when it reponds to #call", }, { :name => :debug, :duck_type => Object, :default_behavior => :nil, :description => "prints debug information to the __IO__ specified by __@memory[:stderr]__ (STDERR by default)", }, { :name => :reserved, :duck_type => Object, :default_behavior => :nil, :description => "for future use", }, ], }, ], :return_value => [ { :name => :args, :description => "list of parameters", :duck_type => Array, :default_behavior => [], :params => [ { :name => :reserved, :duck_type => Object, :default_behavior => :nil, :description => "for future use", }, ], }, ],
} # documentation_end
# File lib/rubyment.rb, line 1542 def call_or_itself args=[] stderr = @memory[:stderr] object, return_dont_call, debug, reserved = args debug = debug.nne debug && (stderr.puts "{#{__method__} starting") debug && (stderr.puts "args=#{args.inspect}") will_call = (object.respond_to? :call) && return_dont_call.negate_me debug && (stderr.puts "will_call=#{will_call.inspect}") will_call && (rv = object.call) debug && (stderr.puts "provisory return value: #{rv.inspect}") will_call.negate_me && (rv = object) debug && (stderr.puts "will return #{rv.inspect}") debug && (stderr.puts "#{__method__} returning}") rv end
returns an array having all the valid values for elements of methods_to_call parameter of experiment__http_request_parse
# File lib/rubyment.rb, line 2853 def callable_methods__http_request_parse args=[] methods_to_call = methods_to_call.nne [ :path_info, :request_uri, :content_length, :body, :request_method, :ssl?, :path, :host, :attributes, :accept, :port, :query, :user, :addr, :header, :body, :request_method, :content_type, :keep_alive, :cookies, :http_version, :accept_charset, :query_string, :script_name, :server_name, :accept_encoding, :accept_language, :peeraddr, :raw_header, :continue, :remote_ip, :keep_alive?, :fixup, ] end
alias for bled
# File lib/rubyment.rb, line 1475 def experiment__bled args=[], &block bled args, &block end
given a duck type table, return the entries having methods that o responds to in their first entry.
by default, uses a table useful to determine method_name for the call: o.map.method_name {|a, b| } if o is an Array, it should be each_with_entries: experiment__duck_type__hash_array
[ [] ]
> [[:product, :each_with_key, :itself]]¶ ↑
if o is a Hash, it should be (another) map. experiment__duck_type__hash_array
[ {} ]
> [[:keys, :map, :reversed]]¶ ↑
note that “reversed” means that the order must be |b,a| instead
# File lib/rubyment.rb, line 1872 def experiment__duck_type__hash_array args=[] o, duck_type_table, reserved = args duck_type_table = duck_type_table.nne [ [ :product, :each_with_index, :itself, :to_a ], [ :keys, :map, :reverse, :to_h ], ] rv = duck_type_table.select { |e| responding_method, *r = e o.respond_to? responding_method } rv end
# documentation_begin # short_desc = “parses an http request” @memory.push = {
:function => :experiment__http_request_parse, :short_desc => short_desc, :description => "", :params => [ { :name => :args, :description => "list of parameters", :duck_type => Array, :default_behavior => [], :params => [ { :name => :request, :duck_type => [String, :array_of_strings], :default_behavior => :nil, :description => "for future use", }, :name => :debug, :duck_type => :boolean, :default_behavior => :nil, :description => "prints debug information to the __IO__ specified by __@memory[:stderr]__ (STDERR by default)", }, { :name => :methods_to_call, :duck_type => Array, :default_behavior => [ :path_info, :request_uri, :body, :request_method, :ssl?, ] :description => "methods/properties to extract from a WEBrick::HTTPRequest object -- it must be a valid method callable without parameters.", }, { :name => :output_exceptions, :duck_type => :boolean, :default_behavior => :nil, :description => "exceptions are normally properly handled by inner functions, but setting this to true can be helpful to debug some cases", }, { :name => :reserved, :duck_type => Object, :default_behavior => :nil, :description => "for future use", }, ], }, ], :return_value => [ { :name => :args, :description => "list of parameters", :duck_type => Array, :default_behavior => [], :params => [ { :name => :reserved, :duck_type => Object, :default_behavior => :nil, :description => "for future use", }, ], }, ],
} # documentation_end
# File lib/rubyment.rb, line 2790 def experiment__http_request_parse args=[] request, debug, methods_to_call, output_exceptions, reserved = args stderr = @memory[:stderr] debug = debug.nne debug && (stderr.puts "{#{__method__} starting") debug && (stderr.puts "caller=#{caller_label}") debug && (stderr.puts "args.each_with_index=#{args.each_with_index.entries.inspect}") # debug && (stderr.puts "backtrace=#{backtrace}") output_exceptions = output_exceptions.nne methods_to_call = methods_to_call.nne [ :path_info, :request_uri, :body, :request_method, :ssl?, ] request = (containerize request.nne "").join debug && (stderr.puts "=#{}") require 'webrick' require 'stringio' req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP) block = bled [ :no_answer.to_nil, :no_rescue.negate_me, output_exceptions, ] { req.parse(StringIO.new(request)) req } parse_return = block.first.call methods_result_return = send_enumerator [ methods_to_call, req.method(:send), :args_to_method.array__is(nil), :block_to_method.__is(:whatever), :insert_iterating_element_at.__is(0), :debug.__is(nil), :no_output_exceptions.__is(output_exceptions.negate_me), :rescuing_exceptions.__is(nil), :return_not_only_first.__is(true), ] methods_result = methods_result_return.transpose[0] rv = [ req, methods_to_call, methods_result, parse_return, methods_result_return, ] debug && (stderr.puts "#{__method__} will return #{rv.inspect}") debug && (stderr.puts "#{__method__} returning}") rv end
# short_desc = “creates an http response, after executing the GET ”
@memory.push = {
:function => :experiment__http_response_invoke, :short_desc => short_desc, :description => "", :params => [ { :name => :args, :description => "list of parameters", :duck_type => Array, :default_behavior => "interpreted as empty array", :params => [ { :name => :request, :duck_type => String, :default_behavior => :nil :description => "ignored, will redirect whatever request is made. nil is used.", }, { :name => :location, :duck_type => String, :default_behavior => "", :description => "Location: field value (the url to redirect to)", }, { :name => :code, :duck_type => String, :default_behavior => "200 OK", :description => "Request code", }, { :name => :version, :duck_type => String, :default_behavior => "1.1", :description => "HTTP protocol version", }, { :name => :debug, :duck_type => Object, :default_behavior => :nil, :description => "prints debug information to the __IO__ specified by __@memory[:stderr]__ (STDERR by default)", }, { :name => :eol, :duck_type => Object, :default_behavior => "\r\n", :description => "separator to join each line of the response", }, { :name => :debug_request_parse, :duck_type => :boolean, :default_behavior => :nil, :forwarded => [ { :to => experiment__http_request_parse , :as => :debug } ], }, { :name => :output_exceptions, :duck_type => :boolean, :default_behavior => :nil, :description => "exceptions are normally properly handled by inner functions, but setting this to true can be helpful to debug some cases", }, { :name => :reserved, :duck_type => Object, :default_behavior => "interpreted as nil", :description => "for future use", }, ], }, ],
}
# File lib/rubyment.rb, line 2968 def experiment__http_response_invoke args = [] request, location, code, version, debug, eol, debug_request_parse, output_exceptions, reserved = args stderr = @memory[:stderr] stdout = @memory[:stdout] debug = debug.nne debug && (stderr.puts "{#{__method__} starting") debug && (stderr.puts "caller=#{caller_label}") debug && (stderr.puts "args.each_with_index=#{args.each_with_index.entries.inspect}") request_parse = experiment__http_request_parse [ request, debug_request_parse, :methods_to_call.to_nil, output_exceptions, ] debug && (stderr.puts "request_parse[2]=#{request_parse[2]}") require "shellwords" # request_parse[2][0] is the the request_uri # remove any starting slashes before sending to invoke: args_for_rubyment = Shellwords.split(request_parse[2][0].to_s.gsub /\/*/, "") debug && (stderr.puts "args_for_rubyment=#{args_for_rubyment}") request_stdout = StringIO.new request_stderr = StringIO.new # not thread-safe: @memory[:stdout] = request_stdout @memory[:stderr] = request_stderr block = bled [ :no_answer.to_nil, :no_rescue.negate_me, :output.negate_me, ] { invoke args_for_rubyment } invoke_result = block.first.call @memory[:stdout] = stdout @memory[:stderr] = stderr require 'json' payload = ({ "invoke_result" => invoke_result, "request_stdout" => request_stdout.string, "request_stderr" => request_stderr.string, }).to_json debug && (stderr.puts "payload=#{payload}") location = location.nne "" version = version.nne "1.1" code = code.nne "200 OK" eol = eol.nne "\r\n" rv = http_response_base [ payload, :content_type.to_nil, code, version, :keep_alive.to_nil, debug, eol, location, ] debug && (stderr.puts "#{__method__} will return #{rv.inspect}") debug && (stderr.puts "#{__method__} returning}") rv end
# short_desc = “creates an http response, after executing the GET ”
@memory.push = {
:function => :experiment__http_response_invoke_clone, :short_desc => short_desc, :description => "", :params => [ { :name => :args, :description => "list of parameters", :duck_type => Array, :default_behavior => "interpreted as empty array", :params => [ { :name => :request, :duck_type => String, :default_behavior => :nil :description => "ignored, will redirect whatever request is made. nil is used.", }, { :name => :location, :duck_type => String, :default_behavior => "", :description => "Location: field value (the url to redirect to)", }, { :name => :code, :duck_type => String, :default_behavior => "200 OK", :description => "Request code", }, { :name => :version, :duck_type => String, :default_behavior => "1.1", :description => "HTTP protocol version", }, { :name => :debug, :duck_type => Object, :default_behavior => :nil, :description => "prints debug information to the __IO__ specified by __@memory[:stderr]__ (STDERR by default)", }, { :name => :eol, :duck_type => Object, :default_behavior => "\r\n", :description => "separator to join each line of the response", }, { :name => :debug_request_parse, :duck_type => :boolean, :default_behavior => :nil, :forwarded => [ { :to => experiment__http_request_parse , :as => :debug } ], }, { :name => :output_exceptions, :duck_type => :boolean, :default_behavior => :nil, :description => "exceptions are normally properly handled by inner functions, but setting this to true can be helpful to debug some cases", }, { :name => :reserved, :duck_type => Object, :default_behavior => "interpreted as nil", :description => "for future use", }, ], }, ],
}
# File lib/rubyment.rb, line 3170 def experiment__http_response_invoke_clone args = [] request, location, code, version, debug, eol, debug_request_parse, output_exceptions, reserved = args stderr = @memory[:stderr] stdout = @memory[:stdout] debug = debug.nne debug && (stderr.puts "{#{__method__} starting") debug && (stderr.puts "caller=#{caller_label}") debug && (stderr.puts "args.each_with_index=#{args.each_with_index.entries.inspect}") request_parse = experiment__http_request_parse [ request, debug_request_parse, :methods_to_call.to_nil, output_exceptions, ] debug && (stderr.puts "request_parse[2]=#{request_parse[2]}") require "shellwords" # request_parse[2][0] is the the request_uri # remove any starting slashes before sending to invoke: args_for_rubyment = Shellwords.split(request_parse[2][0].to_s.gsub /\/*/, "") debug && (stderr.puts "args_for_rubyment=#{args_for_rubyment}") request_stdout = StringIO.new request_stderr = StringIO.new # not thread-safe: @memory[:stdout] = request_stdout @memory[:stderr] = request_stderr block = bled [ :no_answer.to_nil, :no_rescue.negate_me, :output.negate_me, ] { invoke args_for_rubyment } invoke_result = block.first.call @memory[:stdout] = stdout @memory[:stderr] = stderr html_request_stdout = request_stdout.string.split("\n") html_request_stderr = request_stderr.string.split("\n") require 'json' payload = CGI.escapeHTML JSON.pretty_generate({ "invoke_result" => invoke_result, "request_stdout" => html_request_stdout, "request_stderr" => html_request_stderr, }) debug && (stderr.puts "args_for_rubyment.size=#{args_for_rubyment.size}") debug && (stderr.puts "args_for_rubyment.size.nne=#{args_for_rubyment.size.nne}") debug && (stderr.puts "args_for_rubyment.size.nne.negate_me=#{args_for_rubyment.size.nne.negate_me}") args_for_rubyment.size.nne.negate_me && (payload = html_content__basic_shell) debug && (stderr.puts "payload=#{payload}") location = location.nne "" version = version.nne "1.1" code = code.nne "200 OK" eol = eol.nne "\r\n" rv = http_response_base [ payload, :content_type.to_nil, code, version, :keep_alive.to_nil, debug, eol, location, ] debug && (stderr.puts "will return #{rv.inspect}") debug && (stderr.puts "#{__method__} returning}") rv end
c = :c experiment__input_select
[[:a, :b, :c], c ]
# File lib/rubyment.rb, line 1735 def experiment__input_select args=[] alternatives, default, reserved = args stderr = @memory[:stderr] caption = alternatives.each_with_index.map {|a, i| "#{i} - #{a.inspect}"}.join("\n") stderr.puts "[alternatives: #{caption}][default: #{default.inspect}]" alternative = input_single_line selection = alternative.nne && alternatives[alternative.to_i] || default end
for each leaf of a (which normally is an Array or Hash), calls block_to_send_to_leaf giving the leaf as arg, (or return the leaf in the case block_to_send_to_leaf is nil). modifies tuples and deep_keys so it contains the results, the deep_keys and the tuples at each step. direct_cycle_placeholder => object to place when a directed cycled (ie, the object is already present in its stack) is found. defaults to :direct_cycle_placeholder. undirect cycle: same thing, but searches in the visited_nodes. Don't use nil, 0, "" as cycleplace holders, use a value v which returns itself if called v.nne; it means that the default should be used BFS: only problem: this uniq should work on object ID
x[:tuples].transpose.transpose.flatten.uniq
> [{:a=>{:b=>:c}, :d=>{:e=>nil}}, {:b=>:c}, {:e=>nil}]¶ ↑
# File lib/rubyment.rb, line 1910 def experiment__recursive_array__visitor args=[] graph_object, block_to_send_to_leaf, deep_keys, duck_type_detector, debug, duck_type_table, tuples, stack, visited_nodes, direct_cycle_placeholder, undirect_cycle_placeholder, undirected_graph, reserved = args recursion_args = args.dup stderr = @memory[:stderr] debug = debug.nne debug && (stderr.puts "{#{__method__} starting") debug && (stderr.puts "caller=#{caller_label}") debug && (stderr.puts "args.each_with_index=#{args.each_with_index.entries.inspect}") undirect_cycle_placeholder = undirect_cycle_placeholder.nne ":undirect_cycle_placeholder" direct_cycle_placeholder = direct_cycle_placeholder.nne ":direct_cycle_placeholder" # structures one per node: nne deep_keys = deep_keys.nne [] stack = stack.nne [] # structures shared by all nodes: just ensure exists tuples ||= [] visited_nodes ||= [] # old_debug = debug # debug = (graph_object.keys.index :b) rescue old_debug debug && (stderr.puts "=#{}") debug && (stderr.puts "graph_object.object_id=#{graph_object.object_id}") object_id_method_name = :object_id_method_name # cycles detection section undirected_cycle = undirected_graph && ( visited_nodes.map(&:object_id).index graph_object.object_id ) debug && undirected_graph && (stderr.puts "visited_nodes_with_oid=#{visited_nodes.map{|y| [y, y.object_id] }}") debug && (stderr.puts "undirected_cycle=#{undirected_cycle.inspect}") directed_cycle = stack.map(&:object_id).index graph_object.object_id debug && (stderr.puts "stack_with_oid=#{stack.map{|y| [y, y.object_id] }}") debug && (stderr.puts "directed_cycle=#{directed_cycle.inspect}") cycle_placeholder = ( directed_cycle && direct_cycle_placeholder || undirected_cycle && undirect_cycle_placeholder ) cycle_placeholder && (a = cycle_placeholder) cycle_placeholder.negate_me && (a = graph_object) # debug = old_debug visited_nodes.push a stack.push a # detecting the type of object. depending if Hash or Array, # methods to call are different. duck_type_detector = duck_type_detector.nne :map duck_type_def = experiment__duck_type__hash_array( [ a, duck_type_table ]) iterating_method = duck_type_def.transpose[1].to_a.first final_method = duck_type_def.transpose[2].to_a.first revert_method = duck_type_def.transpose[3].to_a.first leaf = nil result = (a.respond_to? duck_type_detector) && a.send(iterating_method).map {|a, b| e, i = *([a, b].send(final_method)) debug && (stderr.puts "e, i=#{[e, i]}") recursion_args[0] = e deep_keys.push i recursion_args[2] = deep_keys.dup recursion_args[6] = tuples recursion_args[7] = stack.dup recursion_args[8] = visited_nodes recursion_args[9] = directed_cycle recursion_args[10] = undirected_cycle debug && (stderr.puts "recursion_args.each_with_index=#{recursion_args.each_with_index.entries.inspect}") child_result = send __method__, recursion_args deep_keys.pop [i, child_result] } || ( block_to_send_to_leaf && (leaf = block_to_send_to_leaf. call a) !block_to_send_to_leaf && (leaf = a) tuples.push [ deep_keys, leaf, stack, [:cycle_to_stack_index, directed_cycle], [:cycle_to_visited_nodes_index, undirected_cycle], ] leaf ) # rebuilding the graph object after visits rebuilt_object = (nil.send revert_method) rescue result (result.respond_to? duck_type_detector) && ( result.map {|i, e| rebuilt_object[i] = e[:result] # rebuilt_object[i] = (e[:result] rescue e) } ) rv = { :visited_nodes => visited_nodes, :tuples => tuples, :result => rebuilt_object, } # stack.pop debug && (stderr.puts "will return #{rv.inspect}") debug && (stderr.puts "#{__method__} returning}") rv end
# documentation_begin # short_desc = “tests the function experiment__tester
” @memory.push = {
:function => :experiment__tester, :short_desc => short_desc, :description => "", :params => [ { :name => :args, :description => "list of parameters", :duck_type => Array, :default_behavior => [], :params => [ { :name => :test_cases, :duck_type => Array, :default_behavior => :[], :description => "Array having the fields: __test_id__, __test_expected_value__ and __actual_params__. __actual_params__ is an __Array__ having as first member __method_name__ to be called, and all its remaining args __method_args__ (a __splat__) will be given to __method_name__", }, { :name => :debug, :duck_type => Object, :default_behavior => :nil, :description => "prints debug information to the __IO__ specified by __@memory[:stderr]__ (STDERR by default)", }, { :name => :reserved, :duck_type => Object, :default_behavior => :nil, :description => "for future use", }, ], }, ], :return_value => [ { :name => :args, :description => "__true__ if tests were successful, __false__ otherwise", :duck_type => :boolean, }, ],
} # documentation_end
# File lib/rubyment.rb, line 1695 def experiment__tester args=[] stderr = @memory[:stderr] test_cases, debug, reserved = args debug = debug.nne debug && (stderr.puts "{#{__method__} starting") debug && (stderr.puts "caller=#{caller_label.inspect}") debug && (stderr.puts "args=#{args.inspect}") rv = tester_with_bled [ test_cases, debug, :use_first_of_bled_return.__is(true), ] debug && (stderr.puts "will return #{rv.inspect}") debug && (stderr.puts "#{__method__} returning}") rv end
# documentation_begin # short_desc = “this improves experiment__tester
by encapsulating the bled block building, calls experiment__tester
too ” @memory.push = {
:function => :experiment__tester_with_bled, :short_desc => short_desc, :description => "", :params => [ { :name => :args, :description => "list of parameters", :duck_type => Array, :default_behavior => [], :params => [ { :name => :test_cases_method_args, :duck_type => Object, :default_behavior => :nil, :description => "for future use", }, { :name => :test_cases_array, :duck_type => Object, :default_behavior => :nil, :description => "for future use", }, { :name => :debug, :duck_type => :boolean, :default_behavior => :nil, :description => "prints debug information to the __IO__ specified by __@memory[:stderr]__ (STDERR by default)", }, { :name => :debug_experiment__tester, :duck_type => :boolean, :default_behavior => :nil, :forwarded => [ { :to => :experiment__tester, :as => :debug } ], }, { :name => :output_exceptions, :duck_type => :boolean, :default_behavior => :nil, :description => "exceptions are normally properly handled by inner functions, but setting this to true can be helpful to debug some cases", }, { :name => :to_method_debug, :duck_type => :boolean, :default_behavior => :nil, :forwarded => [ { :to => :to_method , :as => :to_method_debug } ], }, { :name => :to_object_method_debug, :duck_type => :boolean, :default_behavior => :nil, :forwarded => [ { :to => :to_method , :as => :to_object_method_debug } ], }, { :name => :reserved, :duck_type => Object, :default_behavior => :nil, :description => "for future use", }, ], }, ], :return_value => [ { :name => :args, :description => "list of parameters", :duck_type => Array, :default_behavior => [], :params => [ { :name => :reserved, :duck_type => Object, :default_behavior => :nil, :description => "for future use", }, ], }, ],
} # documentation_end
# File lib/rubyment.rb, line 2517 def experiment__tester_with_bled args=[] stderr = @memory[:stderr] test_cases_method, test_cases_method_args, test_cases_array, debug, debug_experiment__tester, output_exceptions, to_method_debug, to_object_method_debug, no_rescue, reserved = args debug = debug.nne debug && (stderr.puts "{#{__method__} starting") debug && (stderr.puts "caller=#{caller_label}") debug && (stderr.puts "args=#{args.inspect}") test_cases_array = test_cases_array.nne [] test_cases_method_args = test_cases_method_args.nne [] test_cases_from_method = (to_method [ test_cases_method, to_method_debug, to_object_method_debug, no_rescue, ]).call *test_cases_method_args debug && (stderr.puts "test_cases_array.size=#{test_cases_array.size}") debug && (stderr.puts "test_cases_from_method.size=#{test_cases_from_method.size}") test_cases = test_cases_from_method.to_a + test_cases_array.to_a debug && (stderr.puts "test_cases.size=#{test_cases.size}") experiment__tester_block = bled [ nil, no_rescue, output_exceptions, ] { experiment__tester [ test_cases, debug_experiment__tester, ] } debug && (stderr.puts "experiment__tester_block=#{experiment__tester_block.inspect}") rv = experiment__tester_block.first.call debug && (stderr.puts "will return first of #{rv.inspect}") !rv.first && (stderr.puts "{#{__method__}: failed with arguments=#{args.inspect}}") rv[1] && (stderr.puts "{#{__method__} exception caught:") rv[1] && (stderr.puts :exception_output.__is(rv[1][1])) rv[1] && (stderr.puts "#{__method__} exception caught}") debug && (stderr.puts "#{__method__} returning}") rv.first end
# documentation_begin # short_desc = “tests the function experiment__whether
” @memory.push = {
:function => :experiment__whether, :short_desc => short_desc, :description => "", :params => [ { :name => :args, :description => "list of parameters", :duck_type => Array, :default_behavior => [], :params => [ { :name => :condition, :duck_type => :boolean, :default_behavior => :nil, :description => "any condition, used to decided which parameter will be run", }, { :name => :run_if_true, :duck_type => Proc, :default_behavior => :nil, :description => "block will be called if condition is true", }, { :name => :run_if_false, :duck_type => Proc, :default_behavior => :nil, :description => "block will be called if condition is true", }, { :name => :return_dont_run, :duck_type => Array, :default_behavior => [], :description => "forces blocks from being called. first element prevents the return_if_true block to be called (so the object return_if_true is returned). the second applies to run_if_false", }, { :name => :debug, :duck_type => Object, :default_behavior => :nil, :description => "prints debug information to the __IO__ specified by __@memory[:stderr]__ (STDERR by default)", }, { :name => :reserved, :duck_type => Object, :default_behavior => :nil, :description => "for future use", }, ], }, ], :return_value => [ { :name => :rv, :description => "value returned by the block run", :duck_type => Object, :default_behavior => :nil, }, ],
} # documentation_end
# File lib/rubyment.rb, line 1627 def experiment__whether args=[] stderr = @memory[:stderr] condition, run_if_true, run_if_false, return_dont_run, debug, reserved = args debug = debug.nne debug && (stderr.puts "{#{__method__} starting") debug && (stderr.puts "args=#{args.inspect}") return_don_run_true = (containerize return_dont_run)[0] return_don_run_false = (containerize return_dont_run)[1] debug && (stderr.puts "[return_don_run_true, return_don_run_false]=#{[return_don_run_true, return_don_run_false].inspect}") condition && (rv = call_or_itself [run_if_true, return_don_run_true]) debug && (stderr.puts "provisory return value: #{rv.inspect}") condition.negate_me && (rv = call_or_itself [run_if_false, return_don_run_false]) debug && (stderr.puts "will return #{rv.inspect}") debug && (stderr.puts "#{__method__} returning}") rv end
write the second argument of the array args into the filepath in the first argument read it back with load__file_json_quiet
# File lib/rubyment.rb, line 1720 def file__json args=[] require 'json' require 'fileutils' file_path, enum, reserved = args FileUtils.mkdir_p File.dirname file_path File.write file_path, JSON.pretty_generate({ :root.to_s => enum }) end
Takes a file_string definition as input and output a new one.
A file_string definition is an image of a file on a string. Each time this function is called, the image is written to the disk (if set), and the previous file_contents is loaded into the string.
The first element of file_string is a file_path, existing or not.
the returned file_string has the same first element, and the second is either: . unexisting file_path . a string having the file path contents, in the case it is a file_path . a list of file_strings, one per each file inside a directory, in the case file_path is a directory.
This function, after generating the file_string to be returned, will write file_path accordingly to the second parameter. If : . a string: will write the string to the file_path (if file_path is not a directory, otherwise does nothing). . a list of file_strings / nil: will call recursively this function for each of the file_string inside, and will create file_path as directory (if still does not exist).
There is yet a third element in a file_string, mode (as in “rw+”, and not as in permissions), used as parameter for file write. Check ruby-doc.org/core-2.3.1/IO.html#method-c-new
This function does not have semantics to be called from the command line in its full interface, because it differentiates nil from “”
Planned improvements: permissions, shallow cat of a dir.
Examples:
# – case: touch (non existing path and empty string) file_string__experimental
[“non_existing_path”, “”]
# – case: echo > (existing or not path (can't be a dir) and non empty string) file_string__experimental
[“existing_or_not_path__file”, “contents of file”]
# – case: echo >> (existing path (no dir) and non empty string, “a” mode) file_string__experimental
[“existing_or_not_path__file”, “contents of file”, “a”]
# – case: cat (path exists, (dir or file) otherwise becomes mkdir, nil string – it is a recursive cat in the case of directories ) file_string__experimental
[“existing_path”]
# --- case: mkdir (or mkdir -p with only one argument): (non existing filepath, no string)
file_string__experimental
[“non_existing_path”]
# -- case: mkdir -p (non existing filepath, no string)
file_string__experimental
[“a/b/c/d”]
# File lib/rubyment.rb, line 3366 def file_string__experimental file_string args = file_string file_path, string_or_file_strings, mode, reserved = containerize(args) # if file_path is a directory, calls recursively this # function, retrieving the file_string representation # for each entry in a subdirectory: file_strings_entries = File.directory?(file_path) && ( Dir.new(file_path).entries ).nne([]).map { |file_path_entry| next_file_path = [file_path, file_path_entry].join("/") # To avoid infinite recursion, we need to check if # the next file path is not something like the # parent with "/./" at the end. # It is not simple to normalize file paths: # https://stackoverflow.com/a/53884097/533510 # It makes more difficult the fact that the next # may not yet exist (although the parent must exist). # But the parent has to exist. And, if the next # and the parent are the same, then both exist. In # that case, we case compare if both have the # same inode. inodes = [ [ File.stat(file_path).ino, File.stat(File.dirname file_path).ino, ], :index, ( bled_call { File.stat(next_file_path).ino } ).first, ] skip = invoke__basic_sender_array(inodes) skip.negate_me && # recursive call send(__method__, [next_file_path]) || nil }.compact # what is considered to be a file_path's contents? # this value will be the string_or_file_strings of # the returned value file_contents = # first case: it's a directory, thus its contents. file_strings_entries || ( # second case: plain file, thus its contents as string bled_call { File.read(file_path) } # third case: non existing file (nil returned) ).first string, file_strings = object__decompose string_or_file_strings # let's just write file_path accordingly # to string_or_file_strings, regardless of file_contents require 'fileutils' bled_call { string && ( # for write matters: # if string, then file_path is a file... FileUtils.mkdir_p File.dirname file_path File.write file_path, string, mode: mode ) || ( # otherwise file_path is a directory... FileUtils.mkdir_p file_path ) } # if string_or_file_strings is a a list of file_strings # so file_path is interpreted to be written as a # directory file_strings = file_strings.map { |next_file_string| next_file_string = next_file_string.as_container # prepend file_path: next_file_string[0] = [ file_path, next_file_string[0].to_s, ].join("/") send __method__, next_file_string # recursive call } [ file_path, file_contents, ] end
# File lib/rubyment.rb, line 1766 def get_self args=[] self end
trying to get the interface compatible with # rest_request_or_open_uri_open # ideally, i would need an equivalent for # rest_response__request_base
# File lib/rubyment.rb, line 2122 def http_request_response__curl args=[] stderr = @memory[:stderr] url, payload, verify_ssl, unimplemented__headers, method, auth_user, password, unimplemented__timeout, unused__skip_open_uri, debug, no_rescuing, output_exception, reserved = args debug = debug.nne debug && (stderr.puts "{#{__method__} starting") debug && (stderr.puts "caller=#{caller_label}") debug && (stderr.puts "args.each_with_index=#{args.each_with_index.entries.inspect}") no_rescuing = no_rescuing.nne output_exception = output_exception.nne method = method.nne "get" verify_ssl = verify_ssl.nne curl_method = "http_#{method.downcase}" curl_post_data = payload.nne curl_args = [url, curl_post_data].compact block = bled [ :no_answer.to_nil, no_rescuing, output_exception, ] { require 'curb' c = Curl::Easy.send(curl_method, *curl_args){|c| c.http_auth_types = :basic c.username = auth_user c.password = password c.ssl_verify_host = verify_ssl c.ssl_verify_peer = verify_ssl c.follow_location = true debug && (stderr.puts "c.ssl_verify_peer=#{c.ssl_verify_peer?}") debug && (stderr.puts "c.ssl_verify_host=#{c.ssl_verify_host?}") } c.perform [ c.body_str, nil, c.http_connect_code] } rv = block.first.call debug && (stderr.puts "#{__method__} will return #{rv.inspect}") debug && (stderr.puts "#{__method__} returning}") rv end
force arguments to be given to method as an array
# File lib/rubyment.rb, line 3076 def invoke_as_array *args method_to_invoke, *args_to_method = args send method_to_invoke, args_to_method end
force arguments to be given to method as a splat
# File lib/rubyment.rb, line 3087 def invoke_as_splat args=[] method_to_invoke, *args_to_method = args send method_to_invoke, *args_to_method end
inverse of file__json
# File lib/rubyment.rb, line 3250 def load__file_json_quiet args=[] require 'json' file_path, debug, reserved = args debug = debug.nne stderr = @memory[:stderr] debug && (stderr.puts "{#{__method__} starting") debug && (stderr.puts "caller=#{caller_label}") debug && (stderr.puts "args=#{args.inspect}") file_contents = File.read file_path debug && (stderr.puts "file_contents size=#{file_contents.size}") loaded = JSON.parse file_contents debug && (stderr.puts "loaded size=#{loaded.size}") debug && (stderr.puts "loaded=#{loaded.inspect}") rv = loaded[:root.to_s] # if raises exception before it will be unbalanced : debug && (stderr.puts "#{__method__} will return #{rv.inspect}") debug && (stderr.puts "#{__method__} returning}") rv end
returns an array having all the paths which are ancestors of path, and path at the end of that array
# File lib/rubyment.rb, line 3042 def parent_dirs__from path path_parent = File.dirname(path) base_case = (path == path_parent) rv = [] base_case.negate_me && ( rv = parent_dirs__from path_parent ) rv.push path end
To generate and execute a code like this:
arrays.map { |a| a.index element } just give as a code_pattern: [ arrays, "map", "index", element, ]
# File lib/rubyment.rb, line 3291 def pattern_exec__mapping_an_object code_pattern iterating_object, # arrays yielding_method_name, # "map" mapping_method_name, # "index" args_to_mapping_method, # element reserved = code_pattern iterating_object.send(yielding_method_name) { |a| a.send mapping_method_name, *args_to_mapping_method } end
enum = (s.scan /http_*/).uniq.map # => #<Enumerator: …> # send_enumerator
[ enum, :gsub, [“http_”, “”] ] # => [“delete”, “get”, “head”, “post”, “put”]
send_enumerator
[ [“tinga_http_tinga”, “http_catepa”], :gsub, [“http_”, “”] ] # => [“tinga_tinga”, “catepa”]
send_enumerator
[ [ [1, 2, 3] ], :map, [], Proc.new {|x| x + 1 } ]
# => [[2, 3, 4]]
send_enumerator
[ [ {}, {} ], :containerize, [], nil, 0] # => [[{}], [{}]]
bug: send_enumerator
[ [ {}, {} ], :method.to_nil, :args.to_nil, Proc.new {} ] # ArgumentError: no method name given
# no bug, just not intuitive usage:
send_enumerator
[ [ {}, {} ], Proc.new {|x| x.size }, [].to_nil, :whatever, 0] # => [0, 0]
# File lib/rubyment.rb, line 1797 def send_enumerator args=[] enum, method, args_to_method, block_to_method, replace_at_index, debug, no_output_exceptions, rescuing_exceptions, return_not_only_first, reserved = args stderr = @memory[:stderr] debug = debug.nne debug && (stderr.puts "{#{__method__} starting") debug && (stderr.puts "caller=#{caller_label}") debug && (stderr.puts "args=#{args.inspect}") args_to_method = args_to_method.nne [] no_output_exceptions = no_output_exceptions.nne rescuing_exceptions = rescuing_exceptions.nne return_not_only_first = return_not_only_first.nne calling_tuples = enum.map {|e| method_name = (!method.respond_to? :call) && method || nil method_to_call = (!method_name) && method || ( (!replace_at_index) && e.method(:send) ) || method(:send) c_t = args_to_method.dup replace_at_index && (c_t[replace_at_index] = e) method_name && (c_t.unshift method_name) c_t.unshift method_to_call debug && (stderr.puts "[e, method_to_call, method_name, replace_at_index]=#{[e, method_name, method_to_call, replace_at_index]}") c_t } debug && (stderr.puts "calling_tuples=#{calling_tuples}") rv = calling_tuples.map {|c_t| block = bled [ :nil, rescuing_exceptions, no_output_exceptions, ] { method_to_call, *args_to_call = c_t method_to_call.call *args_to_call, &block_to_method } return_not_only_first.negate_me && (lrv = block.first.call.first) return_not_only_first && (lrv = block.first.call) lrv } debug && (stderr.puts "will return #{rv.inspect}") debug && (stderr.puts "#{__method__} returning}") rv end
# File lib/rubyment.rb, line 1761 def shell_array_deepen a [ a ] end
# File lib/rubyment.rb, line 1756 def shell_array_first a a.first end
these shell_ functions can take only flatten arrays (intended for ARGV):
# File lib/rubyment.rb, line 1748 def shell_string_split args=[] string, splitter, reserved = args string.split Regexp.new splitter end
will call puts on the stderr
# File lib/rubyment.rb, line 3056 def stderr_puts *args stderr = rubyment_memory__get_key :stderr stderr.puts *args end
will call puts on the stdout
# File lib/rubyment.rb, line 3065 def stdout_puts *args stdout = rubyment_memory__get_key :stdout stdout.puts *args end
# File lib/rubyment.rb, line 2029 def test__experiment__recursive_array__visitor args=[] method_to_test = :experiment__recursive_array__visitor direct_cycle_h = { :a => { :b => [ :c ], }, :d => { :e => nil, }, } direct_cycle_h[:a][:f] = direct_cycle_h[:a] undirect_cycle_h = { :a => { :b => [ :c ], }, :d => { :e => nil, }, } undirect_cycle_h[:d][:g] = undirect_cycle_h[:a] [ (send method_to_test, [ [ 1, [ 2, 3, [ 4 ] ] ], lambda {|x| "a{#{x}}a" }, :deep_keys.to_nil, :duck_type_d.to_nil, :debug_please.negate_me, ]), (send method_to_test, [ { :a => { :b => :c, }, :d => { :e => nil, }, }, lambda {|x| "h{#{x}}h" }, :deep_keys.to_nil, :duck_type_d.to_nil, :debug_please.negate_me, ]), (send method_to_test, [ direct_cycle_h, lambda {|x| "dch{#{x}}dch" }, :deep_keys.to_nil, :duck_type_d.to_nil, :debug_please.negate_me, ]), (send method_to_test, [ undirect_cycle_h, lambda {|x| "uch{#{x}}uch" }, :deep_keys.to_nil, :duck_type_d.to_nil, :debug_please.negate_me, :duck_type_table.to_nil, :tuples.to_nil, :stack.to_nil, :visited_nodes.to_nil, :direct_cycle_placeholder.to_nil, :undirect_cycle_placeholder.to_nil, :undirect_graph, ]), (send method_to_test, [ undirect_cycle_h, lambda {|x| "not_uch{#{x}}not_uch" }, :deep_keys.to_nil, :duck_type_d.to_nil, :debug_please.negate_me, :duck_type_table.to_nil, :tuples.to_nil, :stack.to_nil, :visited_nodes.to_nil, :direct_cycle_placeholder.to_nil, :undirect_cycle_placeholder.to_nil, :undirect_graph.negate_me, ]), ] end
tests experiment__web_http_https_server, creating two servers, one ssl and another plain, redirecting to the ssl one. then, opens a client thread with a client connecting to the root document of the plain server (and in the end being served by the root document of the ssl server). note that this function, with default values will run forever. client_loop_times must be set (to at least 1)
# File lib/rubyment.rb, line 2186 def test__experiment__web_http_https_server args = ARGV stderr = @memory[:stderr] tcp_ssl_server_method, http_processing_method, http_processing_method_args, http_server_port, http_ip_addr, priv_pemfile, cert_pem_file, extra_cert_pem_files, ssl_cert_pkey_chain_method, debug_tcp_ssl_server_method, happy_with_request, io_method, io_method_debug, domain, admit_non_ssl, plain_http_processing_method, plain_http_processing_method_args, plain_http_server_port, plain_http_ip_addr, no_debug_client, client_loop_times, reserved = args tcp_ssl_server_method = tcp_ssl_server_method.nne :experiment__web_http_https_server domain = domain.nne "localhost" http_server_port = http_server_port.nne 8003 plain_http_server_port = plain_http_server_port.nne 8004 no_debug_client = no_debug_client.nne client_loop_times = client_loop_times.nne Float::INFINITY servers = send tcp_ssl_server_method, [ http_processing_method, http_processing_method_args, http_server_port, http_ip_addr, priv_pemfile, cert_pem_file, extra_cert_pem_files, ssl_cert_pkey_chain_method, debug_tcp_ssl_server_method, happy_with_request, io_method, io_method_debug, admit_non_ssl, plain_http_processing_method, plain_http_processing_method_args, plain_http_server_port, plain_http_ip_addr, ] thread_client = Thread.new { (1..client_loop_times).map { |i| response = test__file_read__uri_root [ domain, plain_http_server_port, admit_non_ssl, no_debug_client.negate_me, ] sleep 2 } } thread_client.join true end
Just alias to experiment__tester_with_bled
containerize test_cases__send_enumerator
# File lib/rubyment.rb, line 2704 def test__send_enumerator args=[] debug, reserved = args stderr = @memory[:stderr] debug = debug.nne debug && (stderr.puts "{#{__method__} starting") debug && (stderr.puts "caller=#{caller_label}") debug && (stderr.puts "args=#{args.inspect}") rv = experiment__tester_with_bled [:test_cases__send_enumerator] debug && (stderr.puts "will return #{rv.inspect}") debug && (stderr.puts "#{__method__} returning}") rv end
give as first element in args to experiment__tester_with_bled
# File lib/rubyment.rb, line 2570 def test_cases__send_enumerator args=[] testing_method = :send_enumerator test_cases ||= [ [ :test_case_id.__is("array_base"), :expectation.array__is("post", "get"), :get_actual_results_with.array__is( testing_method, :testing_method_args.array__is( :enum.array__is("http_post", "http_get"), :method_to_each_in_enum.__is(:gsub), :args_to_method.array__is("http_", ""), :block_to_method.__is(:whatever), :insert_iterating_element_at.__is(:ensure.__is(nil)), :debug.__is(false), :no_output_exceptions.__is(nil), :rescuing_exceptions.__is(nil), :return_not_only_first.__is(nil), ), ), ].__note("end of array_base"), [ :test_case_id.__is("two_hashes_base"), :expectation.array__is( [{}], [{}], ), :get_actual_results_with.array__is( testing_method, :testing_method_args.array__is( [ {}, {} ], :containerize, [], :block_to_method.__is(:whatever), :insert_iterating_element_at.__is(0), :debug.__is(nil), :no_output_exceptions.__is(nil), :rescuing_exceptions.__is(nil), :return_not_only_first.__is(nil), ), ), ].__note("end of two_hashes_base"), [ :test_case_id.__is("two_hashes_size"), :expectation.array__is(0, 0), :get_actual_results_with.array__is( testing_method, :testing_method_args.array__is( [ {}, {} ], Proc.new {|x| x.size }, [].to_nil, :block_to_method.__is(:whatever), :insert_iterating_element_at.__is(0), :debug.__is(nil), :no_output_exceptions.__is(nil), :rescuing_exceptions.__is(nil), :return_not_only_first.__is(nil), ), ), ].__note("end of two_hashes_size"), [ :test_case_id.__is("distribute_methods_over_object_v1"), :expectation.array__is( "Test", "TEST", ), :get_actual_results_with.array__is( testing_method, :testing_method_args.array__is( ["capitalize", "upcase" ], Proc.new {|method| "test".send method }, nil, :block_to_method.__is(:whatever), :insert_iterating_element_at.__is(0), :debug.__is(nil), :no_output_exceptions.__is(nil), :rescuing_exceptions.__is(nil), :return_not_only_first.__is(nil), ), ), ].__note("end of distribute_methods_over_object_v1"), [ :test_case_id.__is("distribute_methods_over_object_v2"), :expectation.array__is( "Test", "TEST", ), :get_actual_results_with.array__is( testing_method, :testing_method_args.array__is( ["capitalize", "upcase" ], "test".method(:send), :args_to_method.__is(nil), :block_to_method.__is(:whatever), :insert_iterating_element_at.__is(0), :debug.__is(nil), :no_output_exceptions.__is(nil), :rescuing_exceptions.__is(nil), :return_not_only_first.__is(nil), ), ), ].__note("end of distribute_methods_over_object_v2"), [ :test_case_id.__is("array_map"), :expectation.array__is( [2, 3, 4], ), :get_actual_results_with.array__is( testing_method, :testing_method_args.array__is( :enum.array__is([1, 2, 3]), :method_to_each_in_enum.__is(:map), :args_to_method.__is(nil), :block_to_method.__is(Proc.new {|x| x + 1 }), :insert_iterating_element_at.__is(:ensure.__is(nil)), :debug.__is(nil), :no_output_exceptions.__is(nil), :rescuing_exceptions.__is(nil), :return_not_only_first.__is(nil), ), ), ].__note("end of array_map"), ] end
# documentation_begin # short_desc = “natural improvement of experiment__tester
: but protect each case from exception throwing”, @memory.push = {
:function => :tester_with_bled, :short_desc => short_desc, :description => "", :params => [ { :name => :args, :description => "list of parameters", :duck_type => Array, :default_behavior => [], :params => [ { :name => :test_cases, :duck_type => Array, :default_behavior => :[], :description => "Array having the fields: __test_id__, __test_expected_value__ and __actual_params__. __actual_params__ is an __Array__ having as first member __method_name__ to be called, and all its remaining args __method_args__ (a __splat__) will be given to __method_name__", }, { :name => :debug, :duck_type => Object, :default_behavior => :nil, :description => "prints debug information to the __IO__ specified by __@memory[:stderr]__ (STDERR by default)", }, { :name => :use_first_of_bled_return, :duck_type => Object, :default_behavior => :nil, :description => "will ignore the exception report information returned by bled, and use only the first value.", }, { :name => :output_exceptions, :duck_type => :boolean, :default_behavior => :nil, :description => "exceptions are normally properly handled by inner functions, but setting this to true can be helpful to debug some cases", :forwarded => [ { :to => :bled, :as => :output_exceptions } ], }, { :name => :no_rescue, :duck_type => :boolean, :default_behavior => :nil, :description => "don't protect against exceptions happening", :forwarded => [ { :to => :bled, :as => :dont_rescue } ], }, { :name => :reserved, :duck_type => Object, :default_behavior => :nil, :description => "for future use", }, ], }, ], :return_value => [ { :name => :args, :description => "__true__ if tests were successful, __false__ otherwise", :duck_type => :boolean, }, ],
} # documentation_end
# File lib/rubyment.rb, line 2366 def tester_with_bled args=[] stderr = @memory[:stderr] test_cases, debug, use_first_of_bled_return, output_exceptions, no_rescue, reserved = args debug = debug.nne debug && (stderr.puts "{#{__method__} starting") debug && (stderr.puts "caller=#{caller_label.inspect}") debug && (stderr.puts "args=#{args.inspect}") use_first_of_bled_return = use_first_of_bled_return.nne test_cases = test_cases.nne [ # [ :id, :expectation, :actual_params ], # :actual_params: array with :method_name + :method_args ] expectation = {} actual = {} debug && (stderr.puts "test_cases.size=#{test_cases.size}") test_cases.each_with_index{ |test_case| debug && (stderr.puts "test_case=[test_case_id, test_expectation, actual_params]=#{test_case.inspect}") test_case_id, test_expectation, actual_params = test_case actual_params_method_name, *actual_params_method_args = actual_params debug && (stderr.puts "will send: #{actual_params_method_name.to_s}(*#{actual_params_method_args.inspect})") block = bled [ nil, no_rescue, output_exceptions, ] { send actual_params_method_name, *actual_params_method_args } result = block.first.call expectation[test_case_id] = test_expectation use_first_of_bled_return && (actual[test_case_id] = result.first) use_first_of_bled_return.negate_me && (actual[test_case_id] = result) debug && (stderr.puts "[test_expectation.hash, result.hash]=#{[test_expectation.hash, result.hash].inspect}") } judgement = actual.keys.map {|test_case| [expectation[test_case], actual[test_case] , test_case] }.map(&method("expect_equal")).all? rv = judgement debug && (stderr.puts "will return #{rv.inspect}") debug && (stderr.puts "#{__method__} returning}") rv end
returns a timestamp in the format “%Y.%m.%d_%H:%M:%S”
# File lib/rubyment.rb, line 2422 def time__now_strftime_default Time.now.strftime("%Y.%m.%d_%H:%M:%S") end
calls a function with the processing arg @param [Array] args
, an Array
whose elements are expected to be:
processing_arg
method
- Method, String
method_args
- Array
-
args to be given to the
transform_method_name
on_object
- String, Boolean
debug
- Boolean
output_exceptions
- Boolean
@return [String] processing_arg
# File lib/rubyment.rb, line 2266 def transform_call args = ARGV processing_arg, method, method_args, on_object, debug, output_exceptions, reserved = args stderr = @memory[:stderr] debug = debug.nne debug && (stderr.puts "{#{__method__} starting") debug && (stderr.puts "caller=#{caller_label}") debug && (stderr.puts "args.each_with_index=#{args.each_with_index.entries.inspect}") object_arg = on_object.nne && processing_arg || nil to_method_block = bled [ nil, :no_rescue.negate_me, output_exceptions, ] { to_method( [method, object_arg]).call( [processing_arg] + method_args ) } rv = to_method_block.first.call debug && (stderr.puts "will return first of: #{rv.inspect}") debug && (stderr.puts "#{__method__} returning}") rv.first end