[RUBY] Technology for reading source code (cheat sheet)

1 Overview

According to what I hear, 80% of the work is time to read the source code. However, despite the scale of 80%, there is no impression that the public is actively discussing how to read the source code, and there are also websites and books that summarize how to read the source code systematically and in order. Few. Although I was wondering, I read the source code for a long time by referring to how to read using a debugger, the contents of readable code, and Web articles.

However, the information about the source code reading method was scattered in the memo app, and I felt that the source code reading technology was not systematically acquired forever. Therefore, in this paper, we have compiled a cheat sheet on how to efficiently read the source code from various documents regardless of media such as books, Web articles, and YouTube. The purpose of making a cheat sheet is "to make it easier to look back and repeat and long-term memory" and "to systematically summarize knowledge about source code reading and to make it easier to retrieve information by centralizing information". is there. Also, the language assumed in this article is Ruby, which is familiar to me.

2 Hierarchy in code reading

The code reading has the following layers.

sourcecode-reading-knowledge-group.png

Set the serial numbers as follows.

  1. Each line written as source code
  2. Basic grammar
  3. Library framework
  4. Design patterns, data structures / algorithms, paradigms / principles
  5. IDE (development tool), debugger (debugging tool), execution environment
  6. Team rules
  7. Business knowledge, business requirements, non-functional requirements (what you want to achieve)

The reading comprehension in this image of "knowledge group that constitutes the act of code reading" is 1 → 7 in terms of serial number. Reading from the details to the whole is called code reading.

However, this is a reading comprehension method when you have finished understanding the program to some extent, and in the case of an error or the first day of project participation, 7 → 5 → 6 → 4 → 3 → 2 → 1 (I read in this order) However, I think that reading from the whole to the details like (style is free) is suitable for grasping the program. Therefore, in this paper, we will describe in the order assuming an error or reading the source code on the first day of project participation.

As an aside, I think that the "knowledge group that constitutes the act of code reading" is an excellent figure in that the method of reading the source code is layered and classified.

Then, I will explain in detail the technology for reading the source code from the next article.

3 Purpose setting

The program to read has been decided. What do you do now? If you just read from main without any policy, you won't understand what the code is trying to say. First, clearly define the purpose of reading the code and focus on it. Even when you have to read everything, divide the path and read each part. (* 1)

** ⑦ Business knowledge, business requirements, non-functional requirements (what you want to achieve) ** in the above image correspond to this. "To solve the error" and "To understand the project" are applicable, and specifically, "I want to solve it because it became NoMethodError" and "I want to implement the like function" are set as the purpose.

By the way, the author stores the knowledge gained through work and self-study on a daily basis in a cheat sheet format by dividing it into functional requirements and non-functional requirements in order to achieve the purpose quickly. I want to create a search function! When I think (), I want to change the column by referring to the functional requirement this! When you think, refer to the non-functional requirement this. If you save an error that you are addicted to once in a cheat sheet format, you can refer to the URL twice without any hassle when you encounter the same error. This also leads to psychological stability.

For the time being, I use genuine iOS notepad and InkDrop to create cheat sheets, and use blogs and Qiita to output to the outside. It is very good that the source code that seems to be good to read such as OSS can be reused by storing it on GitHub one by one.

Example of cheat sheet

4 Dynamic analysis

Roughly speaking, analysis methods can be classified into static methods and dynamic methods. The static method is to read the source code itself. The dynamic method is to follow the movement at runtime using a debugger or the like. Basically, it is better to start the analysis with a dynamic analysis. Static analysis is more or less predicting the behavior of a program. On the other hand, it is a fact to see by dynamic analysis. It's easier to get directions and reduce mistakes if you look at the facts first. Is it similar to taking a profile before optimizing? It may be said that the case is resolved first from the scene. (* 1)

It seems. Therefore, we will explain from the dynamic method.

In addition, in this paper, dynamic analysis is performed for the purpose of "solving errors", but the source code is also dynamically analyzed for "the purpose of understanding the project". Please convert the "If an error occurs" part to "If you find the source code you care about in the project" as appropriate.

4.1 Use the debugger

I think that Web programming is when a client sends a request with parameters, processes it on the server side, and responds to the client. Sometimes, the value is brought from the database with reference to the parameter value, processed on the server side, and responded to the client. In other words, Web programming is a bucket relay race and a relay race. The water in the bucket and the sash became just variables. And the error occurs because the value of the variable is different from the expectation or the rule of the tournament is not logical.

The debugger analyzes which point in the bucket relay flow caused an error. Determine the location of the error that matches the purpose determined in "1 Setting the purpose" from the browser, URL, and backtrace, and infer and search the corresponding folder and file from the project file by making full use of the given name. To do. By doing so, the file name, function name, variable name, type name, and member name that look like it are specified, and a debugger is inserted at a specific point to grasp the flow of variables.

By using a debugger, a program that was recognized in the brain as static character information can be recognized in the brain as a dynamic landscape at once. Personally, I feel something close to the excitement when a photo 80 years ago suddenly became a movie and started to move. By grasping the program as an image, the right brain and spatial perception can be used. Since the processing flow can be stocked in the right brain, which has a large storage capacity, the source code can be analyzed in the vacant left brain.

If it is an IDE, use the debugger built into Eclipse or JetBrain IDE. If not, for Ruby you can use a third-party library such as byebug or pry.

4.2 Write down the source code processing flow in Japanese or in a memo

In 4.1, I read the backtrace and used the debugger to understand the process flow of the source code. After grasping the processing flow, the next step is to write the grasped contents in Japanese or in a memo.

Why "replace the source code processing flow with Japanese and make a memo"? There are two reasons.

The first is "because the source code is abstract".

I think that deciphering the source code is to put an abstract concept into a concrete concept. A genius or an engineer with long work experience can understand abstraction as it is and utilize it, but I am an ordinary person with little work experience in programming. Therefore, I think that incorporating an abstract concept into a concrete concept and taking notes in Japanese is an important factor in terms of work efficiency, learning, and external storage of thinking. Therefore, it is important to "replace the source code processing flow with Japanese and make a memo".

The second is "because the source code is written in English".

First of all, we are Japanese. I use Japanese for 24 hours. What is written in Japanese can be understood in 0 seconds and the image is easy to understand. Unfortunately, the source code is written in English. I'm not familiar with English, which is not my mother tongue. Even if you say Giraffe in English, you can't understand it right away, but if you say giraffe in Japanese, you can imagine an animal giraffe in your head in 0 seconds. In other words, the meaning of words written in English cannot be understood in 0 seconds, and image memory is more difficult than in Japanese. Therefore, it is important to describe the flow of abstract source code written in English in Japanese or in a memo in a figure in order to speed up the work.

If you want to understand the source code as it is in English, you need to consciously create a habit of understanding English in English and develop your English brain. However, I think it will probably take a considerable amount of time to acquire an English brain. Especially for writing. Also, since I often learn programming and marketing, I can't devote my resources to English. Therefore, it is important to urgently convert the program written in English into Japanese and make a note of the processing flow in order to organize it.

For the above reasons, we thought that it was important to describe the flow of source code processing in Japanese and figures. Actually, I prepared the third thing, "a point where you can understand the process flow from a bird's-eye view", but I omitted the description because I didn't know how to write the detailed sentences.

4.3 Check the behavior of the error part

I was able to grasp the location of the error in 4.1 and the entire processing flow in 4.2.

I think that debugging is an act of hypothesis testing that "at a certain process (row), the data state should be like this".

You can get a general idea of why the error part doesn't work by reading the error message, but sometimes you don't understand why it doesn't work. In such a case, the error can be solved by using the following method. In 3.3, [Introduction to Ruby for those who aim to become professionals](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%92%E7%9B%AE] % E6% 8C% 87% E3% 81% 99% E4% BA% BA% E3% 81% AE% E3% 81% 9F% E3% 82% 81% E3% 81% AERuby% E5% 85% A5% E9 % 96% 80-% E8% A8% 80% E8% AA% 9E% E4% BB% 95% E6% A7% 98% E3% 81% 8B% E3% 82% 89% E3% 83% 86% E3% 82% B9% E3% 83% 88% E9% A7% 86% E5% 8B% 95% E9% 96% 8B% E7% 99% BA% E3% 83% BB% E3% 83% 87% E3% 83% 90% E3% 83% 83% E3% 82% B0% E6% 8A% 80% E6% B3% 95% E3% 81% BE% E3% 81% A7-Software-Design-plus% E3% 82% B7% I referred to Chapter 11 of E3% 83% AA% E3% 83% BC% E3% 82% BA / dp / 4774193976). Since it is a famous book, if you are an experienced Ruby user, you may have heard it once, but it is important in terms of suppressing the basic grammar of ② "Knowledge group that constitutes the act of code reading", so if you are interested, please read it. Ma SHOW TIME.

4.3.1 Solve by yourself

① Read the error message

Copy and paste the error message and google it to solve most problems.

② Read the back trace

Roughly speaking, a backtrace can be used to find out where a method was called from "data representing the method call status". Speaking of rails, use Application Trace.

③ Check the log

It seems that some frameworks such as Rails output logs.

④ Check the progress of the program

Overview

Is my guess and the actual processing behavior correct? I want to find out where the inference of variables and the actual deviation are.

Method

  1. Check the variables by doing print debug or logger debug
  2. Put tap in the method chain and check the variables
  3. Make breakpoints and check variables with Byebug or the standard IDE debugger

⑤ Try it interactively.

This is done when the behavior of the method is different from what you expected, or when you want to check the behavior of the library.

Method

  1. Run simple code with irb
  2. If the error is derived from the framework, reproduce the error part with scaffold.

⑥ Read the library code

If you want to know what the behavior of the external library is, or if it is the cause of the external library itself not working due to version upgrade etc., you need to go down to the code of the library. Since Ruby is a scripting language, the libraries needed to run it should be at hand as Ruby code. The rest can be found by using the source_location method of the Method class to find the location of the library in the project. If the return value is nil (implemented in C language), it is often a method of the Ruby standard library.

In addition, the source code of the library is often excellent as the source code, so if you learn how to write it and store it on GitHub etc., you can reuse it and improve your technical skills.

⑦ Write the test code

merit

  1. Save time on debugging
  2. Can be used instead of documentation that guarantees that the logic of the programs you have created is not broken
  3. You can proactively deal with unexpected errors that are not recognized by your thoughts.

Method

See the test framework for each language.

⑧ Stay away from your computer

Go to the bathroom, go shopping for drinks, take a walk, exercise, take a nap, eat rice, take a bath, go to bed early.

This may solve the problem that you have been worried about for several hours because your view is open.

4.3.2 Rely on others

① In-house & official document

Since both are primary information, I think that they can solve the problem accurately and surely.

② Refer to the information on the net

Refer to Qiita and personal blogs.

③ Search for issue

There seems to be an issue tracking service (I first learned about it). I don't understand the whole sentence in English, but since it is an official issue, I think that if you put it in the corner of your head as an error resolution option, you can solve the problem accurately and surely in case of trouble.

④ Ask someone (workplace person, teratail)

Personally, if I don't understand after investigating for a certain amount of time, that is my limit at the moment, so I would like to ask people after summarizing the main points. However, it is also a method of resistance because it is often bitter.

5 Static analysis

5.1 Read the documentation

Don't read the source code in the first place

I think I will lose if I read the source code.

Reference manuals, documents Design-related documents and materials There should be a lot of great things written in natural language, so read that first.

If you can't rely on them very much, or if they don't help, read the code because it can't be helped. Still, we emphasize the naming of comments and identifiers, and first try to interpret them as meaningfully as possible.

In the case where there are no comments and the variable name is appropriate, there is no help for it. There's nothing else you can do, so let's take a look at the code logic.

It's a hassle to read, so it's the first thing you don't want to do if you can. Think of ways to avoid doing it as much as possible.

If you are a beginner, you will often not be able to make progress due to lack of reading comprehension, and unless you are under pressure of great need, you should say, "You should improve your code reading a little more."

The predecessor should have left the document, so read it. https://teratail.com/questions/147782

This is also similar to the previous section, so let's first know the specifications. Also, if there is a document that explains the internal structure, I definitely want to see it. Check if there are files with names such as "HACKING" and "TOUR".

It corresponds to ** ⑥ team rule ** in the "knowledge group that constitutes the act of code reading". Since the predecessor has taken the time to leave the document in natural language and figures, it is better to read the document first if there is one.

5.2 Understanding of structure and design

It corresponds to ** ④ design pattern, data structure / algorithm, paradigm / principle ** in "knowledge group that constitutes the act of code reading".

5.2.1 Read directory structure

See how the directory is divided. Get an overview of how the program is designed and what parts it has. See how each module is related.

5.2.2 Read the file structure

While looking at the function (name) contained in the file, see how the file is divided. The filename is like an unabated comment and should be noted.

Also, I would like to make a point about the naming rules for function names. Most C programs use prefixes for extern functions, which can be used to identify the type of function. Also, in an object-oriented program, the function affiliation information may be included in the prefix, which is valuable information. (Example: rb_str_push)

5.2.3 Understand the call relationship between functions

The next most important information after the function name. This is important, especially if you have a large number of functions. I want to use the tool for this. It's best if you have a tool that can make a diagram, but if you don't have one, you only need to draw the most important parts, so it's a good idea to draw the diagram yourself. You don't have to elaborate on the diagram, so it's enough to draw it roughly on the backing paper.

By the way, a diagram of the relationship between these calls is sometimes called a call graph. The static call graph is a diagram of the call relationships written in the source code as it is, and the dynamic call graph is a diagram that shows only the functions that were called when they were actually operated. call graph).

However, it seems that in Japanese sentences, "call graph" implicitly refers to dynamic call graph, and static call graph is often referred to as "function call relation". However, it is easier to understand if it is paired with static and dynamic, so I call it dynamic call graph / static call graph.

I think the call graph was one of the features of Eclipse when I was doing Java. Even if I look it up in "Ruby Call Graph" or "vscode Call Graph", it doesn't come out and I don't understand the contents in detail, so I'll put it in the corner of my head for the time being. If you want to know, please search.

5.2.4 Design pattern

A design pattern is "a pattern of a commonly used design in object-oriented programming" and "a solution to a similar problem that is encountered many times". By knowing the design pattern, you can enjoy the following merits when reading and writing the source code.

merit

  1. Highly reusable program
  2. Efficiently create high quality structure
  3. Excellent maintainability due to high readability
  4. If you know the design pattern, you will be able to read the design intent, so it will be easier to maintain when taking over.
  5. By turning around and knowing the design pattern, communication between developers becomes smooth.

Summary of GoF design patterns

Material of design pattern using Ruby as an example

Design pattern for ordinary people by ordinary people Act 1 Public

5.2.5 Algorithm and data structure

A program is like winning another half if you know what the data structure is like. When writing code, it's much more useful to explain the data structure (only) than to comment on the code one by one. (And it was written in some book, what is it?)

  • Addition: It was "program writing method". The following is quoted from p.168 of the same book. "One of the most effective ways to explain a program is to simply explain in detail how to allocate the data. What are the possible values for the main variables? If you explain how it changes, you can say that the explanation of the program has advanced a lot. " By the way, the original book of this book was published in 1974.

  • Addendum 2: I found a similar comment in "C Programming Diagnosis Room". The following is quoted from p.78 of the same book. "Prohibit flowcharts. Flowcharts are not good because they allow you to write the flow of control in" various ". The program is for processing the data, and the difference in the data changes the flow of control. To the last, data is the main subject. Depending on how you define data such as variables and arguments, the ease of programming will be greatly improved. Diagrams of what your data structures look like are much more useful than flowcharts. Write down the meaning of the data. "

Quiet talk. Of course, if you want to create a data structure in C, you should use struct or union. Such important structures are often defined in header files. Of course, the internal structure may be defined in .c, and some data structures are dynamically constructed, so in the end you will not know until you read the function. Still, you should read the header file first. The filename is still important when reading the header file. For example, if there is a file called frame.h in the language processing system, it is probably the definition of the stack frame.

Focus on structure members when predicting data structures. If there is a pointer next in the structure definition, you can imagine that it is a linked list. Similarly, if there are elements such as parent, children, and sibling, it is a tree out of ten.

I have no practical experience with algorithms and data structures, so I'm not sure how to use them. Apparently, it is often used when performing big data analysis. It is thought that understanding of the literature will be deepened by reading the following.

STEP1

[26 algorithms that can be seen in the algorithm picture book](https://www.amazon.co.jp/%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA% E3% 82% BA% E3% 83% A0% E5% 9B% B3% E9% 91% 91-% E7% B5% B5% E3% 81% A7% E8% A6% 8B% E3% 81% A6% E3 % 82% 8F% E3% 81% 8B% E3% 82% 8B26% E3% 81% AE% E3% 82% A2% E3% 83% AB% E3% 82% B4% E3% 83% AA% E3% 82 % BA% E3% 83% A0-% E7% 9F% B3% E7% 94% B0% E4% BF% 9D% E8% BC% 9D-ebook / dp / B07179Q3MJ)

App "Algorithm Picture Book"

Wakuwaku Academy (YouTube)

STEP2

AtCoder: Japan's largest site for holding competitive programming contests

Please let me know if you have any other recommendations!

5.3 Understand the meaning of the source code

5.3.1 Read word by word

Which of the files, functions (methods), types (classes), variables, member variables, and reserved words does the word appear in the source code? Know how to write.

① File

There are naming conventions for frameworks such as Rails. The file name can be used to infer to some extent what role it plays in software.

② Types of functions (methods)

Methods from the standard library (classes originally included in Ruby, Rails, etc. because they are frequently used and methods associated with them. Inducted into the Hall of Fame)

Method (gem) from external library

Methods from your own library (helper, model, application)

Method options

③ Type of mold

integer, string, array, etc.

In object-oriented programming, types are called classes, and you can create and use classes yourself.

Object-oriented programming terminology

Classes, objects, instances, receivers, methods, messages, states, attributes (attributes, properties)

④ Variable (instance)

Variables, member variables, instance variables, class instance variables

https://qiita.com/mogulla3/items/cd4d6e188c34c6819709

⑤ Class differentiation using namespaces

The purpose is to prevent unexpected collisions of class names.

⑥ Reserved words and identifiers

A word that expresses a structure such as "sequential processing," "conditional branching," and "repetition."

#Reserved words and identifiers in ruby
BEGIN    class    ensure   nil      self     when
END      def      false    not      super    while
alias    defined? for      or       then     yield
and      do       if       redo     true     __LINE__
begin    else     in       rescue   undef    __FILE__
break    elsif    module   retry    unless   __ENCODING__
case     end      next     return   until

⑦ Investigation of abbreviations

List any abbreviations that are difficult to understand and look them up early. For example, if "GC" is written, the story will be quite different depending on whether it is garbage collection or graphic context. In English, there are many things like taking the first letter of a word or eliminating vowels. In particular, abbreviations that are famous in the field of the target program are used without asking questions, so check in advance.

Let me give you an example from what I remember. A certain Lisp processing system uses a prefix called "blt" throughout the program, but I had a problem because I didn't know what this meant. This was actually a built-in function. It's a simple thing to understand, but if you don't understand this, the difficulty level is quite different.

It seems. Certainly I feel like I saw an abbreviation in a Java project. If you don't know

  1. Ask a detailed person
  2. Examine the documentation
  3. Search

You will need to take one of these strategies.

Also, when coding variables etc. by yourself, it is good to refer to the readable code.

5.3.2 Read what the code was designed for

RASIS is one of the evaluation indexes for computer systems, and is an acronym that expresses the five items of "reliability," "availability," "maintainability," "maintainability," and "safety." ..

Created based on What you should be careful about when developing Web services in business (for new graduates). RASIS is not bright, so if you want to know more details, please refer to it.

①Reliability

Strength against system failure "Difficult to break" Indicates the resistance to system failure.

  1. Exceptional design
  2. Complete the deploy / rollback procedure
  3. Life and death monitoring / fault detection
  4. Handle log files properly
  5. Make a backup

②Availability

Requested service is available at the required timing Degree of "service available". Ability to keep the system running.

  1. Eliminate single points of failure

③ Serviceability (extensibility)

Aim for a "simple system". If it is simple, it is easy to grasp the contents and update.

  1. Test code
  2. Variable names according to the readable code naming convention
  3. Version control
  4. Leave the document
  5. Log failure information
  6. Easy development environment

④ Integrity

It refers to the consistency and consistency of data. Often referred to as database data. With Rails, restrictions are placed on the model layer and DB.

  1. Transaction control

What is a transaction? [DB transaction processing in 13 minutes] Database introductory course # 4

  1. DB constraints

[SQL Anti-Patterns](https://www.amazon.co.jp/SQL%E3%82%A2%E3%83%B3%E3%83%81%E3%83%91%E3%82%BF% E3% 83% BC% E3% 83% B3-Bill-Karwin / dp / 4873115892)

Negative spiral that burns database application development

Checklist for avoiding "SQL anti-patterns" ① (DB logical design)

  1. Model design

[Data Model Design and Best Practices (Part 2) --Talend](https://www.talend.com/jp/blog/2019/05/20/data-model-design-best-practices-part-2 /)

What happens if you design the model properly --SlideShare

Easy to understand Domain Driven Design-Learn Domain Model Design with your hands

⑤ Security (safety)

Prevent information from leaking.

  1. SSL
  2. Password hashing
  3. Use framework features
  4. Strong parameter settings
  5. Placeholder settings

5.3.3 Read history

See the commit log on GitHub. It is easy to understand the intention of the developer and which source code is related to the completed module.

How to read large-scale source code

How to read the source code for beginners

6 Let's change it a little and make it work

This is one of the methods, not the kind of "do it at this stage". The human head is a mysterious thing, and it is easy to remember what we did while using various parts of the body as much as possible. I think that the fact that many people prefer manuscript paper to the keyboard of a personal computer is not just a nostalgic hobby, but something like that.

That's why it's very hard to stay on the monitor just to read, so read while rewriting. If you do so, your body will often become familiar with the chords rather quickly. If you find a name or code that you don't like, rewrite it. Abbreviations that are difficult to understand may be replaced with words that are not abbreviated as well as written down.

However, as a matter of course, when rewriting, leave the original source separately, and if you think that the Tsuji 褄 does not match on the way, check the original source. Otherwise, you will end up suffering for hours with your own simple mistakes.

Rewrite and move Similar to the previous section, but here we will actually run the program. For example, try changing the parameters and code slightly in places where the operation is difficult to understand. Then, of course, the behavior changes, so you can infer what the code means.

Needless to say, you should keep the original binaries and do the same for both.

In my experience, I think that the act of changing and checking the operation can improve the programming skill, and it is especially recommended for beginners. However, I have experienced that I cannot undo the changes and get an error and get impatient, and because I am afraid of the error, I stop trying and miss the growth opportunity. So, as a lifeline, I will describe how to cancel the change below.

6.1 Undo what you worked on on Git

Convenient because you can delete DB migration and file creation

git checkout . 
git clean -df .

I want to cancel with git

6.2 Try with interactive features such as irb

Hypothesis testing of how libraries and methods work

rails c --sandbox

Summary of how to follow the source code, how to read it, and tips

7 I want to enjoy reading the source code (I want to work like a game)

  1. Keep a record
  2. Read the source code of the field you are interested in
  3. Read good source code
  4. Read source code that is useful at work
  5. Make a slight change and make it work
  6. Look for bugs

[4 ways programmers teach you to read source code! ](Https://medium.com/traveloco-tech/%E3%81%8A%E3%81%A3%E3%81%95%E3%82%93%E3%83%97%E3%83%AD % E3% 82% B0% E3% 83% A9% E3% 83% 9E% E3% 83% BC% E3% 81% 8C% E6% 95% 99% E3% 81% 88% E3% 82% 8B-% E3% 82% BD% E3% 83% BC% E3% 82% B9% E3% 82% B3% E3% 83% BC% E3% 83% 89% E3% 82% 92% E8% AA% AD% E3% 82% 80% E3% 81% 9F% E3% 82% 81% E3% 81% AE% EF% BC% 94% E3% 81% A4% E3% 81% AE% E6% 96% B9% E6% B3% 95-2c6a2dd28bda) [To new programmers] Read the source code (2/2)

8 At the end

That's about it for the time being. In addition, I will update this sentence from time to time depending on comments from outside and the degree of my own growth.

Recommended Posts

Technology for reading source code (cheat sheet)
Technology for reading Java source code in Eclipse
When reading the source code
C # cheat sheet for Java engineers
Java source code reading java.lang.Math class
Pre-written source code for the activity
Java cheat sheet
JMeter cheat sheet
Kotlin cheat sheet
[Docker cheat sheet]
Mockito + PowerMock cheat sheet
Eclipse Collections cheat sheet
Rails Tutorial cheat sheet
Spring Boot2 cheat sheet
SCSS notation cheat sheet
Oreshiki docker-compose cheat sheet
Docker command cheat sheet
CRuby code reading (2): rb_newobj_of