mysh 0.4.0 → 0.5.0
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 +4 -4
- data/README.md +162 -51
- data/lib/mysh.rb +4 -2
- data/lib/mysh/{external_ruby.rb → external.rb} +6 -7
- data/lib/mysh/handlebars.rb +1 -1
- data/lib/mysh/init.rb +14 -9
- data/lib/mysh/input_wrapper.rb +67 -0
- data/lib/mysh/internal/action.rb +5 -16
- data/lib/mysh/internal/action_pool.rb +1 -1
- data/lib/mysh/internal/actions/cd.rb +8 -15
- data/lib/mysh/internal/actions/command_line.rb +3 -3
- data/lib/mysh/internal/actions/comment.rb +3 -11
- data/lib/mysh/internal/actions/elapsed.rb +9 -16
- data/lib/mysh/internal/actions/exit.rb +4 -11
- data/lib/mysh/internal/actions/gls.rb +2 -2
- data/lib/mysh/internal/actions/help.rb +6 -3
- data/lib/mysh/internal/actions/help/sub_help.rb +2 -2
- data/lib/mysh/internal/actions/history.rb +2 -2
- data/lib/mysh/internal/actions/load.rb +24 -30
- data/lib/mysh/internal/actions/pwd.rb +3 -11
- data/lib/mysh/internal/actions/quit.rb +3 -11
- data/lib/mysh/internal/actions/say.rb +3 -12
- data/lib/mysh/internal/actions/show.rb +16 -19
- data/lib/mysh/internal/actions/show/env.rb +5 -5
- data/lib/mysh/internal/actions/show/ruby.rb +1 -1
- data/lib/mysh/internal/actions/type.rb +11 -17
- data/lib/mysh/internal/actions/vars.rb +2 -2
- data/lib/mysh/internal/actions/vls.rb +11 -16
- data/lib/mysh/internal/manage.rb +5 -19
- data/lib/mysh/process.rb +8 -12
- data/lib/mysh/quick.rb +11 -11
- data/lib/mysh/system.rb +11 -0
- data/lib/mysh/version.rb +1 -1
- data/tests/my_shell_tests.rb +25 -7
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d3adff2eeba99442ae70d9eea972c624906238a1
|
4
|
+
data.tar.gz: 828447d5721f3a973e20ef96d6ad7aa6a82dcbc3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea9d214229c39f0185346032bdcd06b27df9cd241df796b8b427543f593995c4e76706af3f3012625ce335cbf6bb794e9b142aed11f353558505fe19f2822d2c
|
7
|
+
data.tar.gz: 5c30d99b23cb66088fa77a2e71ddf24304d03f118a67f7f1e58a2ec33a0e8b36cd9e2bdb1aeb840d5237a2e7e1a7c05d9f8179bb4c8ceb58ed13fea349a433ba
|
data/README.md
CHANGED
@@ -25,6 +25,10 @@ web sites.
|
|
25
25
|
See the original article at:
|
26
26
|
(http://www.blackbytes.info/2016/07/writing-a-shell-in-ruby/)
|
27
27
|
|
28
|
+
Oh, and one other little thing. A survey of the mysh reveals that it currently
|
29
|
+
contains 2291 lines of code. It seems that there has been some growth beyond
|
30
|
+
the 25 lines in the original article.
|
31
|
+
|
28
32
|
## Installation
|
29
33
|
|
30
34
|
Add this line to your application's Gemfile:
|
@@ -52,21 +56,21 @@ mysh <options>
|
|
52
56
|
|
53
57
|
Where the available options are:
|
54
58
|
|
55
|
-
Option | Short Form
|
56
|
-
|
57
|
-
--debug | -d
|
58
|
-
--no-debug | -nd
|
59
|
-
--help | -? -h
|
60
|
-
--init filename | -i filename
|
61
|
-
--no-init | -ni
|
62
|
-
--load filename | -l filename
|
63
|
-
--post-prompt "str" | -pp "str"
|
64
|
-
--no-post-prompt | -npp
|
65
|
-
--pre-prompt "str" | -pr "str"
|
66
|
-
--no-pre-prompt | -npr
|
67
|
-
--prompt "str" | -p "str"
|
68
|
-
--no-prompt | -np
|
69
|
-
--quit |
|
59
|
+
Option | Short Form(s)| Description | Default
|
60
|
+
---------------------|--------------|-------------------------|-----------
|
61
|
+
--debug | -d | Turn on mysh debugging. | false
|
62
|
+
--no-debug | -nd | Turn off mysh debugging.
|
63
|
+
--help | -? -h | Display mysh usage info and exit.
|
64
|
+
--init filename | -i filename | Initialize mysh by loading the specified file. | ~/mysh_init.mysh
|
65
|
+
--no-init | -ni | Do not load a file to initialize mysh.
|
66
|
+
--load filename | -l filename | Load the specified file into the mysh.
|
67
|
+
--post-prompt "str" | -pp "str" | Set the mysh line continuation prompt to "str". | $prompt
|
68
|
+
--no-post-prompt | -npp | Turn off mysh line continuation prompting.
|
69
|
+
--pre-prompt "str" | -pr "str" | Set the mysh pre prompt to "str". | $w
|
70
|
+
--no-pre-prompt | -npr | Turn off mysh pre prompting.
|
71
|
+
--prompt "str" | -p "str" | Set the mysh prompt to "str". | mysh
|
72
|
+
--no-prompt | -np | Turn off mysh prompting.
|
73
|
+
--quit | | Quit out of the mysh program.
|
70
74
|
|
71
75
|
<br>When mysh is run, the user is presented with a command prompt:
|
72
76
|
|
@@ -90,17 +94,26 @@ and acclimated to its environment. The boot/initialization process of mysh is
|
|
90
94
|
somewhat modeled after (well if I'm honest, more like inspired by) that of the
|
91
95
|
famous bash shell. On startup:
|
92
96
|
|
93
|
-
1.
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
option, or disabled with the --no-init
|
101
|
-
|
102
|
-
|
103
|
-
|
97
|
+
1. Option values are initialized to their initial, default values.
|
98
|
+
2. Process pre-boot command line options: Some command line options are
|
99
|
+
processed early. These are --help, -h, -?, --init, -i, --no-init, and -ni.
|
100
|
+
See Usage above for details on these.
|
101
|
+
3. Try to load and execute the mysh_init file. There are three possible files
|
102
|
+
for this role. They are ~/mysh_init.mysh, ~/mysh_init.rb, and ~/mysh_init.txt.
|
103
|
+
In priority, ".mysh" > ".rb" > ".txt". <br>NOTE: If an init file should be
|
104
|
+
specified with the --init option, or disabled with the --no-init option, this
|
105
|
+
step is skipped.
|
106
|
+
4. The rest of the command line options are processed at this time. Again,
|
107
|
+
see Usage above for details.
|
108
|
+
|
109
|
+
It should be noted that in the event of a conflict in settings during the boot
|
110
|
+
process, the last command/option encountered shall prevail. For example if the
|
111
|
+
~/mysh_init.mysh contains the line:
|
112
|
+
```
|
113
|
+
$debug = on
|
114
|
+
```
|
115
|
+
and the command line has the -nd option, then debug mode will be disabled
|
116
|
+
because the -nd command line option is processed after the mysh_init file.
|
104
117
|
|
105
118
|
###REPL
|
106
119
|
|
@@ -110,6 +123,10 @@ Print and Loop and is used in may utilities like irb, pry and the rails
|
|
110
123
|
console. To better use mysh, it is good to understand each of these four
|
111
124
|
operating steps.
|
112
125
|
|
126
|
+
For more information on REPLs please see:
|
127
|
+
(https://en.wikipedia.org/wiki/Read-eval-print_loop) and
|
128
|
+
(https://repl.it/languages/ruby)
|
129
|
+
|
113
130
|
####READ
|
114
131
|
|
115
132
|
The first step is just to get input from the user. For interactive sessions
|
@@ -175,7 +192,6 @@ character in the input. These signature characters are:
|
|
175
192
|
below.
|
176
193
|
* @ to get information about the system, its environment, and the ruby
|
177
194
|
installation. For more information see Shell Info below.
|
178
|
-
|
179
195
|
2. Internal Commands - These commands are recognized by having the first word
|
180
196
|
in the input match a word stored in an internal hash of command actions. For
|
181
197
|
more information see Internal Commands below.
|
@@ -333,8 +349,8 @@ for setting a variable is:
|
|
333
349
|
$name=value
|
334
350
|
|
335
351
|
Where:
|
336
|
-
* name is a word matching the regex: /[a-z][a-z0-9_]*/.
|
337
|
-
* value is
|
352
|
+
* name is a word matching the regex: /[a-z][a-z0-9_]*/. Note: lower case only.
|
353
|
+
* value is some text, with optional embedded variables and handlebars.
|
338
354
|
|
339
355
|
To erase the value of a variable, use:
|
340
356
|
|
@@ -490,6 +506,8 @@ environment.
|
|
490
506
|
|
491
507
|
Topic | Description
|
492
508
|
---------|----------------------------------------------------
|
509
|
+
version | The version of mysh in use.
|
510
|
+
init file| The init file in use or <none found> or <none>.
|
493
511
|
user | The current user name.
|
494
512
|
home | The current home directory.
|
495
513
|
name | The path/name of the mysh program currently executing.
|
@@ -546,9 +564,11 @@ say <stuff> | Display the text in the command arguments.
|
|
546
564
|
type file | Display a text file with support for optional embedded handlebars and mysh variables.
|
547
565
|
vls {mask} | Display the loaded modules, matching the optional mask, that have version info.
|
548
566
|
|
549
|
-
|
550
|
-
|
551
|
-
|
567
|
+
Notes:
|
568
|
+
1. The notation {x} means that x is optional.
|
569
|
+
2. The load command applied to a mysh script file acts exactly the same
|
570
|
+
as if the script file were executed directly from the command line. As a
|
571
|
+
result of this:
|
552
572
|
|
553
573
|
```
|
554
574
|
myfile.mysh
|
@@ -622,28 +642,51 @@ located at:
|
|
622
642
|
A survey of the contents of that folder will reveal the nature of these files.
|
623
643
|
|
624
644
|
New internal commands may also be added in code via the the add_action method
|
625
|
-
of the
|
626
|
-
|
645
|
+
of the Action class of the Mysh module. There are two ways to do this:
|
646
|
+
|
647
|
+
* The command may be created as an instance of the Action class with a command
|
648
|
+
name, description and a block that contains the action to be performed by this
|
649
|
+
command. This block takes one parameter, an input wrapper (see About Command
|
650
|
+
Arguments below for details). This approach is best when the command is simple
|
651
|
+
enough to fit into a single lambda block of code. Like this template:
|
627
652
|
|
628
653
|
```ruby
|
629
654
|
module Mysh
|
630
|
-
|
655
|
+
command_name = 'new <item>'
|
656
|
+
desc = "A succinct description of what this command does."
|
657
|
+
action = lambda do |input|
|
658
|
+
#Action packed stuff goes here!
|
659
|
+
end
|
660
|
+
|
661
|
+
COMMANDS.add_action(Action.new(command_name, desc, &action))
|
662
|
+
end
|
663
|
+
```
|
631
664
|
|
665
|
+
|
666
|
+
* The command may be created as an instance of a sub-class of the Action class.
|
667
|
+
In this case, only a name and description are needed as the sub-class should
|
668
|
+
contain all the needed code. The action method is the process_command and this
|
669
|
+
takes one parameter, an input wrapper (see About Command Arguments below for
|
670
|
+
details). This approach is required when the command action needs to be spread
|
671
|
+
across multiple methods. Like this template:
|
672
|
+
|
673
|
+
```ruby
|
674
|
+
module Mysh
|
675
|
+
class NewCommand < Action
|
632
676
|
#This method is called when the command is executed.
|
633
|
-
def
|
677
|
+
def process_command(input)
|
678
|
+
#Even more action packed stuff goes here!
|
634
679
|
end
|
635
|
-
|
636
680
|
end
|
637
681
|
|
638
682
|
desc = "A succinct description of what this command does."
|
639
683
|
command_name = 'new <item>'
|
640
684
|
COMMANDS.add_action(NewCommand.new(command_name, desc))
|
641
|
-
|
642
685
|
end
|
643
686
|
```
|
644
687
|
|
645
|
-
|
646
|
-
|
688
|
+
##### Command names:
|
689
|
+
The name of the command is a string with optional argument descriptions
|
647
690
|
separated with spaces. The command is the first word of this string. For
|
648
691
|
example a command_name of:
|
649
692
|
|
@@ -653,22 +696,90 @@ example a command_name of:
|
|
653
696
|
|
654
697
|
will create a command called "new" with a title of "new <item>"
|
655
698
|
|
656
|
-
|
657
|
-
|
658
|
-
code handles matters like
|
699
|
+
##### Command descriptions:
|
700
|
+
A string or an array of strings that describe the command. This serves as the
|
701
|
+
descriptive help for the command. The help display code handles matters like
|
702
|
+
word wrap automatically.
|
703
|
+
|
704
|
+
##### About Command Arguments
|
705
|
+
|
706
|
+
The process_command method take one parameter that is an instance of the
|
707
|
+
InputWrapper class. This class provides several ways to access the parts of the
|
708
|
+
command line. These are:
|
709
|
+
|
710
|
+
Method | Description
|
711
|
+
--------------|----------------
|
712
|
+
raw | The raw, unprocessed command line text.
|
713
|
+
cooked | The command line with variables and handlebars expanded.
|
714
|
+
raw_command | The command portion of the raw text.
|
715
|
+
quick_command | The quick command of the raw text.
|
716
|
+
raw_body | The raw text after the command.
|
717
|
+
quick_body | The raw text after the quick command.
|
718
|
+
cooked_body | The cooked text after the command.
|
719
|
+
parsed | The command and parameters parsed into an array of strings.
|
720
|
+
args | The parameters parsed into an array of strings.
|
721
|
+
|
722
|
+
Note: commands are not normally "cooked". Should this be required
|
723
|
+
use the following code snippet:
|
724
|
+
|
725
|
+
```ruby
|
726
|
+
input.raw.preprocess
|
727
|
+
```
|
728
|
+
|
729
|
+
##### Some Useful Helper Methods
|
730
|
+
|
731
|
+
Within the mysh environment, there exists a number of methods designed to make
|
732
|
+
life easier in adding new commands or in load ruby files or embedded into
|
733
|
+
handlebars. Some of these more noteworthy methods are listed below:
|
734
|
+
|
735
|
+
###### MNV[:name]
|
736
|
+
Retrieve the mysh variable "$name"
|
659
737
|
|
660
|
-
|
738
|
+
###### MNV[:name]="value"
|
739
|
+
Set/Update the mysh variable "$name". Note that the value is always a string,
|
740
|
+
even for things like "true" and "false". If the value is an empty string, the
|
741
|
+
variable is deleted.
|
661
742
|
|
662
|
-
|
663
|
-
|
743
|
+
###### mysh "string"
|
744
|
+
Execute the string as a mysh command.
|
664
745
|
|
665
|
-
|
746
|
+
###### Mysh.parse_args("string")
|
747
|
+
Parse the string into an array of arguments.
|
666
748
|
|
667
|
-
|
749
|
+
###### Mysh.input.readline(parms)
|
750
|
+
Get a line of input from the console. See the mini_readline gem for info
|
751
|
+
on the optional parms.
|
668
752
|
|
669
|
-
|
753
|
+
###### "string".preprocess(context=mysh_default_context)
|
754
|
+
Process the string for embedded variables and handlebars. By default,
|
755
|
+
any embedded ruby is evaluated in the mysh global expression binding. However,
|
756
|
+
another BindingWrapper instance may be passed to access an alternative binding.
|
670
757
|
|
671
|
-
|
758
|
+
###### "string".decorate
|
759
|
+
Given a string with a file spec, decorate that string so that it is more
|
760
|
+
pleasing to the local environment. This is a great boon to writing effortless
|
761
|
+
portable code.
|
762
|
+
|
763
|
+
#### Adding Help Topics
|
764
|
+
|
765
|
+
In mysh, help topics are generally implemented as text files often augmented
|
766
|
+
with embedded mysh variables and ruby code. It it noteworthy however that they
|
767
|
+
can also be mysh script or ruby code files. The management of these help files
|
768
|
+
is located in the file:
|
769
|
+
```
|
770
|
+
mysh/lib/mysh/internal/actions/help/sub_help.rb
|
771
|
+
```
|
772
|
+
In this file, you can locate a variable called "help". This is an array of
|
773
|
+
arrays where each line describes a help topic. Within each line is a further
|
774
|
+
array of three strings. Respectively these are:
|
775
|
+
1. The name of the help item.
|
776
|
+
2. A brief description of the help topic. This line is used in the help on help
|
777
|
+
(??) topic.
|
778
|
+
3. The name of the file, **with its extension**, that contains the actual help
|
779
|
+
information.
|
780
|
+
|
781
|
+
To add a new help topic, simply add the new help file to the help folder and
|
782
|
+
and a corresponding line entry to to the help variable.
|
672
783
|
|
673
784
|
## Contributing
|
674
785
|
|
@@ -676,7 +787,7 @@ All participation is welcomed. There are two fabulous plans to choose from:
|
|
676
787
|
|
677
788
|
#### Plan A
|
678
789
|
|
679
|
-
1. Fork it (
|
790
|
+
1. Fork it (https://github.com/PeterCamilleri/mysh/fork)
|
680
791
|
2. Switch to the development branch ('git branch development')
|
681
792
|
3. Create your feature branch ('git checkout -b my-new-feature')
|
682
793
|
4. Commit your changes ('git commit -am "Add some feature"')
|
data/lib/mysh.rb
CHANGED
@@ -7,11 +7,13 @@ require 'in_array'
|
|
7
7
|
|
8
8
|
require_relative 'mysh/exceptions'
|
9
9
|
require_relative 'mysh/binding_wrapper'
|
10
|
+
require_relative 'mysh/input_wrapper'
|
10
11
|
require_relative 'mysh/user_input'
|
11
|
-
require_relative 'mysh/quick'
|
12
12
|
require_relative 'mysh/expression'
|
13
13
|
require_relative 'mysh/internal'
|
14
|
-
require_relative 'mysh/
|
14
|
+
require_relative 'mysh/quick'
|
15
|
+
require_relative 'mysh/external'
|
16
|
+
require_relative 'mysh/system'
|
15
17
|
require_relative 'mysh/handlebars'
|
16
18
|
require_relative 'mysh/shell_variables'
|
17
19
|
require_relative 'mysh/pre_processor'
|
@@ -1,20 +1,20 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
#* mysh/
|
3
|
+
#* mysh/external.rb -- Support for executing external files.
|
4
4
|
module Mysh
|
5
5
|
|
6
|
-
#Try to execute
|
6
|
+
#Try to execute an external file.
|
7
7
|
#<br>Endemic Code Smells
|
8
8
|
#* :reek:TooManyStatements
|
9
|
-
def self.
|
10
|
-
args =
|
9
|
+
def self.try_execute_external(input)
|
10
|
+
args = input.parsed
|
11
11
|
file_name = args.shift
|
12
12
|
|
13
13
|
if (file_name)
|
14
14
|
ext = File.extname(file_name)
|
15
15
|
|
16
16
|
if ext == '.rb'
|
17
|
-
new_command = "#{RbConfig.ruby} #{
|
17
|
+
new_command = "#{RbConfig.ruby} #{input.cooked}"
|
18
18
|
puts "=> #{new_command}" if MNV[:debug]
|
19
19
|
system(new_command)
|
20
20
|
:ruby_exec
|
@@ -22,8 +22,7 @@ module Mysh
|
|
22
22
|
Mysh.process_file(file_name)
|
23
23
|
:mysh_script
|
24
24
|
elsif ext == '.txt'
|
25
|
-
|
26
|
-
show_handlebar_file(file_name, exec_host)
|
25
|
+
show_handlebar_file(file_name, BindingWrapper.new(binding))
|
27
26
|
:internal
|
28
27
|
end
|
29
28
|
end
|
data/lib/mysh/handlebars.rb
CHANGED
@@ -8,7 +8,7 @@ class Object
|
|
8
8
|
#Show a file with embedded ruby handlebars.
|
9
9
|
#<br>Note:
|
10
10
|
#The message receiver is the evaluation host for the handlebar code.
|
11
|
-
def show_handlebar_file(name, evaluator)
|
11
|
+
def show_handlebar_file(name, evaluator = $mysh_exec_host)
|
12
12
|
puts eval_handlebar_file(name, evaluator)
|
13
13
|
end
|
14
14
|
|
data/lib/mysh/init.rb
CHANGED
@@ -9,18 +9,23 @@ module Mysh
|
|
9
9
|
#Perform init phase processing.
|
10
10
|
def self.mysh_load_init
|
11
11
|
|
12
|
-
unless $mysh_init_file
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
12
|
+
unless $mysh_init_file
|
13
|
+
|
14
|
+
if (home = ENV['HOME'])
|
15
|
+
names = [home + '/mysh_init.mysh',
|
16
|
+
home + '/mysh_init.rb',
|
17
|
+
home + '/mysh_init.txt']
|
18
|
+
|
19
|
+
$mysh_init_file = names.detect {|name| File.file?(name)}
|
20
|
+
end
|
21
|
+
|
22
|
+
if $mysh_init_file
|
23
|
+
mysh "load #{$mysh_init_file.decorate}"
|
24
|
+
else
|
25
|
+
$mysh_init_file = '<none found>'
|
20
26
|
end
|
21
27
|
end
|
22
28
|
|
23
|
-
$mysh_init_file = '<none found>' unless $mysh_init_file
|
24
29
|
end
|
25
30
|
|
26
31
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#* mysh/internal/input_wrapper.rb -- An action compatible wrapper for a input.
|
4
|
+
module Mysh
|
5
|
+
|
6
|
+
#* mysh/internal/input_wrapper.rb -- An action compatible wrapper for a input.
|
7
|
+
class InputWrapper
|
8
|
+
|
9
|
+
#Build an input wrapper.
|
10
|
+
def initialize(raw)
|
11
|
+
@raw = raw.chomp
|
12
|
+
@raw_command = @raw_body = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
#Access the raw text.
|
16
|
+
attr_reader :raw
|
17
|
+
|
18
|
+
#Get the first raw character.
|
19
|
+
def quick_command
|
20
|
+
@raw[0] || ""
|
21
|
+
end
|
22
|
+
|
23
|
+
#Get the balance of the raw string.
|
24
|
+
def quick_body
|
25
|
+
@raw[1..-1] || ""
|
26
|
+
end
|
27
|
+
|
28
|
+
#Get the command word if it exists.
|
29
|
+
def raw_command
|
30
|
+
@raw_command ||= @raw.split[0] || ""
|
31
|
+
end
|
32
|
+
|
33
|
+
#Get the parameter text.
|
34
|
+
def raw_body
|
35
|
+
@raw_body ||= @raw[(raw_command.length)..-1]
|
36
|
+
end
|
37
|
+
|
38
|
+
#Get the preprocessed argument text.
|
39
|
+
def cooked_body
|
40
|
+
raw_body.preprocess
|
41
|
+
end
|
42
|
+
|
43
|
+
#Access the massaged text.
|
44
|
+
def cooked
|
45
|
+
raw_command + cooked_body
|
46
|
+
end
|
47
|
+
|
48
|
+
#Get the parsed arguments
|
49
|
+
def args
|
50
|
+
Mysh.parse_args(cooked_body)
|
51
|
+
end
|
52
|
+
|
53
|
+
#Get the parsed command line.
|
54
|
+
def parsed
|
55
|
+
[raw_command] + args
|
56
|
+
end
|
57
|
+
|
58
|
+
#Set up input for a quick style command.
|
59
|
+
def quick
|
60
|
+
@raw_command = quick_command
|
61
|
+
@raw_body = quick_body
|
62
|
+
self
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|