From abfa30340cfa98d5c309db8665ef0cc2126dbc35 Mon Sep 17 00:00:00 2001 From: TantumErgo <9907196+TantumErgo@users.noreply.github.com> Date: Thu, 5 Sep 2019 13:59:52 -0400 Subject: [PATCH 1/2] Edited typos and basic grammatical mistakes First run-through. Need to go back and check all edits. Did not edit slang use or lack of capitalization of proper nouns throughout the text. --- _i18n/en.yml | 198 +++++++++++++++++++++++++-------------------------- 1 file changed, 99 insertions(+), 99 deletions(-) diff --git a/_i18n/en.yml b/_i18n/en.yml index ef1ec3d..25c57d9 100644 --- a/_i18n/en.yml +++ b/_i18n/en.yml @@ -1,5 +1,5 @@ head: - title: "Ruby Fundamental" + title: "Ruby Fundamentals" metatags: description: "Fundamental programming with ruby examples and references. It covers threads, SOLID principles, design patterns, data structures, algorithms." keywords: "Ruby, Fundamental, Ruby programming fundamental. Ruby gotchas, Functional programming, Metaprogramming, Threads, Ruby solid principles with examples, Ruby design patterns with examples, Ruby algorithms with examples, Ruby data structures with examples." @@ -92,7 +92,7 @@ sidebar: submenus: - surprising - quotes - - twue + - twue #What is this word? - symbols_and_strings - string_or_nothing - constants @@ -132,11 +132,11 @@ sidebar: submenus: - single - open_close - - liskov + - liskov #What is this word? Seems to be incorrect translation - segregation - - di - - title: "Become Ruby Meister" - url: ruby_meister + - di #What does this mean? + - title: "Become Ruby Meister" #Do you mean Become Ruby MASTER, or do you mean Meister? Master would be better English, Meister is made-up slang + url: ruby_meister #See comment on line 138 - title: Threads url: threads submenus: @@ -154,7 +154,7 @@ pages: title: "Page not found :(" description: "The requested page could not be found." page500: - title: "Something was going wrong :(" + title: "Something went wrong :(" #My edit is much better English algorithms: title: "Algorithms" complexity: @@ -175,13 +175,13 @@ pages: description: "From the comparison presented here, one might conclude that selection sort should never be used. It does not adapt to the data in any way (notice that the four animations above run in lockstep), so its runtime is always quadratic. However, selection sort has the property of minimizing the number of swaps. In applications where the cost of swapping items is high, selection sort very well may be the algorithm of choice." shell_sort: title: "Shell sort" - description: "The worst-case time complexity of shell sort depends on the increment sequence. For the increments 1 4 13 40 121 ...,which is what is used here, the time complexity is O(n32). For other increments, time complexity is known to be O(n43) and even O(n·lg2(n)). Neither tight upper bounds on time complexity nor the best increment sequence is known. Because shell sort is based on insertion sort, shell sort inherits insertion sort’s adaptive properties. The adaptation is not as dramatic because shell sort requires one pass through the data for each increment, but it is significant. For the increment sequence shown above, there are log3(n) increments, so the time complexity for nearly sorted data is O(n·log3(n)). Because of its low overhead, relatively simple implementation, adaptive properties, and sub-quadratic time complexity, shell sort may be a viable alternative to the O(n·lg(n)) sorting algorithms for some applications when the data to be sorted is not very large." + description: "The worst-case time complexity of shell sort depends on the increment sequence. For the increments 1 4 13 40 121 ..., which is what is used here, the time complexity is O(n32). For other increments, time complexity is known to be O(n43) and even O(n·lg2(n)). Neither the tight upper bounds on the time complexity nor the best increment sequence is known. Because shell sort is based on insertion sort, shell sort inherits insertion sort’s adaptive properties. The adaptation is not as dramatic, because shell sort requires one pass through the data for each increment, but it is significant. For the increment sequence shown above, there are log3(n) increments, so the time complexity for nearly-sorted data is O(n·log3(n)). Because of its low overhead, relatively simple implementation, adaptive properties, and sub-quadratic time complexity, shell sort may be a viable alternative to the O(n·lg(n)) sorting algorithms for some applications when the data to be sorted is not very large." heap_sort: title: "Heap sort" - description: "Heapsort is simple to implement, performs an O(n·lg(n)) in-place sort, but is not stable. The first loop, the Θ(n) “heapify” phase, puts the array into heap order. The second loop, the O(n·lg(n)) “sort down” phase, repeatedly extracts the maximum and restores heap order. The sink function is written recursively for clarity. Thus, as shown, the code requires Θ(lg(n)) space for the recursive call stack. However, the tail recursion in sink() is easily converted to iteration, which yields the O(1) space bound. Both phases are slightly adaptive, though not in any particularly useful manner. In the nearly sorted case, the heapify phase destroys the original order. In the reversed case, the heapify phase is as fast as possible since the array starts in heap order, but then the sort down phase is typical. In the few unique keys case, there is some speedup but not as much as in shell sort or 3-way quicksort." + description: "Heap sort is simple to implement, performs an O(n·lg(n)) in-place sort, but is not stable. The first loop, the Θ(n) “heapify” phase, puts the array into heap order. The second loop, the O(n·lg(n)) “sort down” phase, repeatedly extracts the maximum and restores heap order. The sink function is written recursively for clarity. Thus, as shown, the code requires Θ(lg(n)) space for the recursive call stack. However, the tail recursion in sink() is easily converted to iteration, which yields the O(1) space bound. Both phases are slightly adaptive, though not in any particularly useful manner. In the nearly-sorted case, the heapify phase destroys the original order. In the reversed case, the heapify phase is as fast as possible, since the array starts in heap order, but then the sort down phase is typical. In the few unique keys case, there is some speedup, but not as much as in shell sort or 3-way quicksort." merge_sort: title: "Merge sort" - description: "Merge sort is very predictable. It makes between 0.5lg(n) and lg(n) comparisons per element, and between lg(n) and 1.5lg(n) swaps per element. The minima are achieved for already sorted data; the maxima are achieved, on average, for random data. If using Θ(n) extra space is of no concern, then merge sort is an excellent choice: It is simple to implement, and it is the only stable O(n·lg(n)) sorting algorithm. Note that when sorting linked lists, merge sort requires only Θ(lg(n) extra space (for recursion). Merge sort is the algorithm of choice for a variety of situations: when stability is required, when sorting linked lists, and when random access is much more expensive than sequential access (for example, external sorting on tape). There do exist linear time in-place merge algorithms for the last step of the algorithm, but they are both expensive and complex. The complexity is justified for applications such as external sorting when Θ(n) extra space is not available." + description: "Merge sort is very predictable. It makes between 0.5lg(n) and lg(n) comparisons per element, and between lg(n) and 1.5lg(n) swaps per element. The minima are achieved for already-sorted data; the maxima are achieved, on average, for random data. If using Θ(n) extra space is of no concern, then merge sort is an excellent choice: It is simple to implement, and it is the only stable O(n·lg(n)) sorting algorithm. Note that when sorting linked lists, merge sort requires only Θ(lg(n) extra space (for recursion). Merge sort is the algorithm of choice for a variety of situations: when stability is required, when sorting linked lists, and when random access is much more expensive than sequential access (for example, external sorting on tape). There do exist linear time in-place merge algorithms for the last step of the algorithm, but they are both expensive and complex. The complexity is justified for applications such as external sorting when Θ(n) extra space is not available." quick_sort: title: "Quick sort" description: "When carefully implemented, quicksort is robust and has low overhead. When a stable sort is not needed, quicksort is an excellent general-purpose sort – although the 3-way partitioning version should always be used instead. The 2-way partitioning code shown above is written for clarity rather than optimal performance; it exhibits poor locality, and, critically, exhibits O(n2) time when there are few unique keys. A more efficient and robust 2-way partitioning method is given in Quicksort is Optimal by Robert Sedgewick and Jon Bentley. The robust partitioning produces balanced recursion when there are many values equal to the pivot, yielding probabilistic guarantees of O(n·lg(n)) time and O(lg(n)) space for all inputs. With both sub-sorts performed recursively, quick sort requires O(n) extra space for the recursion stack in the worst case when recursion is not balanced. This is exceedingly unlikely to occur, but it can be avoided by sorting the smaller sub-array recursively first; the second sub-array sort is a tail recursive call, which may be done with iteration instead. With this optimization, the algorithm uses O(lg(n)) extra space in the worst case." @@ -204,7 +204,7 @@ pages: credits: "Code and articles were taken from resources:" data_structures: title: "Data structures" - description: "In computer science, big O notation is used to classify algorithms by how they respond to changes in input size, such as how the processing time of an algorithm changes as the problem size becomes extremely large. In analytic number theory it is used to estimate the \"error committed\" while replacing the asymptotic size of an arithmetical function by the value it takes at a large finite argument. A famous example is the problem of estimating the remainder term in the prime number theorem." + description: "In computer science, big O notation is used to classify algorithms by how they respond to changes in input size, such as how the processing time of an algorithm changes as the problem size becomes extremely large. In analytic number theory, it is used to estimate the \"error committed\" while replacing the asymptotic size of an arithmetical function by the value it takes at a large finite argument. A famous example is the problem of estimating the remainder term in the prime number theorem." axioms: title: "Basic axioms of data structures" description: "The running time performance of the common language runtime is given by a set of axioms which we shall now postulate." @@ -212,15 +212,15 @@ pages: title: "Fetch and store time" description1: "The time required to fetch a reference to an object from memory is a constant, T_fetch, and the time required to store a reference to an object in memory is a constant, T_store" description2: "According to Axiom, the assignment statement has running time T_fetch + T_store. That is, the time taken to fetch the object reference from variable x is T_fetch and the time taken to store that object reference in the variable y is T_store." - description3: "Also has running time T_fetch + T_store. To see why this should be the case, consider that the constant 1 names a Fixnum object with value one. Therefore, we can expect the cost of fetching the reference to the object named 1 is the same as that of fetching a reference to any other object." + description3: "Also has running time T_fetch + T_store. To see why this should be the case, consider that the constant 1 names a Fixnum object with value one. Therefore, we can expect the cost of fetching the reference to the object named 1 to be the same as that of fetching a reference to any other object." elementary_operations: title: "Elementary arithmetic operations time" description1: "The times required to perform elementary arithmetic operations, such as addition, subtraction, multiplication, division, and comparison, are all constants. These times are denoted by T_+, T_-, T_/, T_*, T_<, respectively." - description2: "We can determine time of a statement like is 2 * T_fetch + T_+ + T_store. This is because we need to fetch two object references from the variables y and 1; perform the addition giving a new object whose value is the sum; and, store a reference to the new object in the variable y." + description2: "We can determine the time of a statement like 2 * T_fetch + T_+ + T_store. This is because we need to fetch two object references from the variables y and 1; perform the addition, giving a new object whose value is the sum; and, store a reference to the new object in the variable y." description3: "We shall assume that the alternative requires exactly the same running time as the original statement." call_method: title: "Calling method time" - description1: "The time required to call a method is a constant, T_call, and the time required to return from a method is a constant, T_return The rationale for making the overhead associated with parameter passing the same as the time to store an object reference is that the passing of an argument is conceptually the same as assignment of the actual parameter value to the formal parameter of the method." + description1: "The time required to call a method is a constant, T_call, and the time required to return from a method is a constant, T_return The rationale for making the overhead associated with parameter passing the same as the time to store an object reference is that the passing of an argument is conceptually the same as the assignment of the actual parameter value to the formal parameter of the method." description2: "According to Axiom, the running time of the statement would be T_fetch + 2 * T_store + T_call + T_f(x), where T_f(x) is the running time of method f for input x. The first of the two stores is due to the passing of the parameter x to the method f; the second arises from the assignment to the variable y." calculating: title: "Calculation time" @@ -228,13 +228,13 @@ pages: description2: "This is 3 * T_fetch. Three operand fetches are required: the first to fetch a reference to the array object a; the second to fetch a reference to the index object i; and, the third to fetch a reference to the array element a[i]." object: title: "Object creation time" - description1: "The time required to create a new object instance of a class is a constant, T_new. This time does not include any time taken to initialize the object. By applying Axioms we can determine that the running time of the statement." + description1: "The time required to create a new object instance of a class is a constant, T_new. This time does not include any time taken to initialize the object. By applying Axioms we can determine the running time of the statement." description2: "T_new + T_fetch + 2 * T_store + T_call + T_fixnum_init, where T_fixnum_init is the running time of the initialize method of the class Fixnum." example: title: "Example" description: "In this section we apply Axioms, the analysis of the running time of a program to compute the following simple arithmetic series summation." implementations: - title: "Implementation" + title: "Implementations" stack: title: "Stack" description: "The stack is the sibling of the queue. It mimics a real-life stack (e.g. of paper). It is FILO (first-in-last-out), so that when items are retrieved from the stack, they are returned in the reverse of the order in which they were added. Again, Ruby Arrays provide a perfect container. As with the Queue, it could also be implemented using a linked list." @@ -242,7 +242,7 @@ pages: as_linked_list: "Stack as linked list" queue: title: "Queue" - description: "A queue is a simple container-based structure that mimics a real-life queue (e.g. waiting in line at the bank). It is FIFO (first-in-first-out), meaning that when you retrieve items from the queue, they are returned in the order in which they entered. Ruby Arrays provide methods that make Queue implementation trivially easy but having them named appropriately and contained in a convenience class is worth it to see they are implemented, and because other structures will inherit from this one. An alternate implementation could be done using a linked list." + description: "A queue is a simple container-based structure that mimics a real-life queue (e.g. waiting in line at the bank). It is FIFO (first-in-first-out), meaning that when you retrieve items from the queue, they are returned in the order in which they entered. Ruby Arrays provide methods that make Queue implementation trivially easy, but having them named appropriately and contained in a convenience class #is worth it to see they are implemented, and because other structures will inherit from this one.# An alternate implementation could be done using a linked list." #The text between the two #'s doesn't make clear sense. What is the meaning you want to say? as_array: "Queue as array" as_linked_list: "Queue as linked list" deque: @@ -252,13 +252,13 @@ pages: as_linked_list: "Deque as linked list" singly_linked_list: title: "Singly Linked List" - description: "Singly linked lists contain nodes which have a data field as well as a 'next' field, which points to the next node in line of nodes. Operations that can be performed on singly linked lists include insertion, deletion and traversal." + description: "Singly linked lists contain nodes which have a data field as well as a 'next' field, which points to the next node in a line of nodes. Operations that can be performed on singly linked lists include insertion, deletion, and traversal." doubly_linked_list: - title: "Double linked list" + title: "Doubly linked list" description: "In a doubly-linked list, each list element contains two references--one to its successor and one to its predecessor." ordered_list: title: "Ordered list" - description: "An ordered list is a list in which the order of the items is significant. However, the items in an ordered lists are not necessarily sorted. Consequently, it is possible to change the order of items and still have a valid ordered list." + description: "An ordered list is a list in which the order of the items is significant. However, the items in an ordered list are not necessarily sorted. Consequently, it is possible to change the order of the items and still have a valid ordered list." as_array: "Ordered list as array" hash_table: title: "Hash Table" @@ -268,35 +268,35 @@ pages: description: "A binary tree is a tree in which each node can have a maximum of two children. The children are designated left and right." binary_search_tree: title: "Binary Search Tree<" - description: "In computer science, binary search trees (BST), sometimes called ordered or sorted binary trees, are a particular type of containers: data structures that store \"items\" (such as numbers, names etc.) in memory. They allow fast lookup, addition and removal of items, and can be used to implement either dynamic sets of items, or lookup tables that allow finding an item by its key (e.g., finding the phone number of a person by name)" + description: "In computer science, binary search trees (BST), sometimes called ordered or sorted binary trees, are a particular type of container: data structures that store \"items\" (such as numbers, names etc.) in memory. They allow for fast lookup, addition and removal of items, and can be used to implement either dynamic sets of items, or lookup tables that allow for finding an item by its key (e.g., finding the phone number of a person by name)" b_tree: title: "B-tree" - description: "In computer science, a B-tree is a self-balancing tree data structure that keeps data sorted and allows searches, sequential access, insertions, and deletions in logarithmic time. The B-tree is a generalization of a binary search tree in that a node can have more than two children (Unlike self-balancing binary search trees, the B-tree is optimized for systems that read and write large blocks of data. B-trees are a good example of a data structure for external memory. It is commonly used in databases and filesystems." + description: "In computer science, a B-tree is a self-balancing tree data structure that keeps data sorted and allows for searches, sequential access, insertions, and deletions in logarithmic time. The B-tree is a generalization of a binary search tree in that a node can have more than two children. Unlike self-balancing binary search trees, the B-tree is optimized for systems that read and write large blocks of data. B-trees are a good example of a data structure for external memory. It is commonly used in databases and filesystems." binary_heap: title: "Binary Heap" - description: "A binary heap is a heap-ordered complete binary tree which is implemented using an array. In a heap the smallest key is found at the root and since the root is always found in the first position of the array, finding the smallest key is a trivial operation in a binary heap." + description: "A binary heap is a heap-ordered complete binary tree which is implemented using an array. In a heap, the smallest key is found at the root, and since the root is always found in the first position of the array, finding the smallest key is a trivial operation in a binary heap." credits: "Code and articles were taken from resources:" source: "This page contains the Ruby code from book of \"Data Structures and Algorithms with Object-Oriented Design Patterns in Ruby\" by Bruno R. Preiss. Copyright (c) 2004 by Bruno R. Preiss, P.Eng. All rights reserved." design_patterns: title: "Design patterns" creational: title: "Creational patterns" - description: "In software engineering, creational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic form of object creation could result in design problems or in added complexity to the design. Creational design patterns solve this problem by somehow controlling this object creation. Creational design patterns are composed of two dominant ideas. One is encapsulating knowledge about which concrete classes the system uses. Another is hiding how instances of these concrete classes are created and combined." + description: "In software engineering, creational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic form of object creation could result in design problems or in added complexity to the design. Creational design patterns solve this problem by somehow controlling this object creation. Creational design patterns are composed of two dominant ideas. One is encapsulating knowledge about which concrete classes the system uses. The other is hiding how instances of these concrete classes are created and combined." abstract_factory: title: "Abstract factory pattern" description: "The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes. In normal usage, the client software creates a concrete implementation of the abstract factory and then uses the generic interface of the factory to create the concrete objects that are part of the theme. The client doesn't know (or care) which concrete objects it gets from each of these internal factories, since it uses only the generic interfaces of their products. This pattern separates the details of implementation of a set of objects from their general usage and relies on object composition, as object creation is implemented in methods exposed in the factory interface." builder: title: "Builder pattern" - description: "The builder pattern is an object creation software design pattern. Unlike the abstract factory pattern and the factory method pattern whose intention is to enable polymorphism, the intention of the builder pattern is to find a solution to the telescoping constructor anti-pattern[citation needed]. The telescoping constructor anti-pattern occurs when the increase of object constructor parameter combination leads to an exponential list of constructors. Instead of using numerous constructors, the builder pattern uses another object, a builder, that receives each initialization parameter step by step and then returns the resulting constructed object at once." + description: "The builder pattern is an object creation software design pattern. Unlike the abstract factory pattern and the factory method pattern whose intention is to enable polymorphism, the intention of the builder pattern is to find a solution to the telescoping constructor anti-pattern[citation needed]. The telescoping constructor anti-pattern occurs when the increase of object constructor parameter combinations leads to an exponential list of constructors. Instead of using numerous constructors, the builder pattern uses another object, a builder, that receives each initialization parameter step by step and then returns the resulting constructed object at once." factory: title: "Factory pattern" - description: "In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor." + description: "In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method (either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes) rather than by calling a constructor." prototype: title: "Prototype pattern" - description: "The prototype pattern is a creational pattern along the lines of the factory. The trick with the prototype is that you create new objects by copying a master object. Change that master object and all subsequent objects that you create will go off into life with a copy of the change." + description: "The prototype pattern is a creational pattern along the lines of the factory pattern. The trick with the prototype is that you create new objects by copying a master object. Changes to that master object and all subsequent objects that you create !will go off into life! with a copy of the change." #Return here to fix the bounded part singleton: title: "Singleton pattern" - description: "Ensure a class only has one instance, and provide a global point of access to it. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects." + description: "Ensures a class only has one instance, and provides a global point of access to it. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects." not_covered: title: "Not covered patterns:" lazy: "Lazy initialization" @@ -314,25 +314,25 @@ pages: description: "The composite design pattern is a structural pattern used to represent objects that have a hierarchical tree structure. It allows for the uniform treatment of both individual leaf nodes and of branches composed of many nodes." decorator: title: "Decorator pattern" - description: "In object-oriented programming, the decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. The decorator pattern is often useful for adhering to the Single Responsibility Principle, as it allows functionality to be divided between classes with unique areas of concern." + description: "In object-oriented programming, the decorator pattern (also known as a Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. The decorator pattern is often useful for adhering to the Single Responsibility Principle, as it allows functionality to be divided between classes with unique areas of concern." facade: title: "Facade pattern" - description: "The Facade design pattern is often used when a system is very complex or difficult to understand because the system has a large number of interdependent classes or its source code is unavailable. This pattern hides the complexities of the larger system and provides a simpler interface to the client. It typically involves a single wrapper class which contains a set of members required by client. These members access the system on behalf of the facade client and hide the implementation details." + description: "The Facade design pattern is often used when a system is very complex or difficult to understand because the system has a large number of interdependent classes or its source code is unavailable. This pattern hides the complexities of the larger system and provides a simpler interface to the client. It typically involves a single wrapper class which contains a set of members required by the client. These members access the system on behalf of the facade client and hide the implementation details." flyweight: title: "Flyweight pattern" - description: "In computer programming, flyweight is a software design pattern. A flyweight is an object that minimizes memory use by sharing as much data as possible with other similar objects; it is a way to use objects in large numbers when a simple repeated representation would use an unacceptable amount of memory. Often some parts of the object state can be shared, and it is common practice to hold them in external data structures and pass them to the flyweight objects temporarily when they are used." + description: "In computer programming, flyweight is a software design pattern. A flyweight is an object that minimizes memory use by sharing as much data as possible with other similar objects; it is a way to use objects in large numbers when a simple repeated representation would use an unacceptable amount of memory. Often, some parts of the object state can be shared, and it is common practice to hold them in external data structures and pass them to the flyweight objects temporarily when they are used." proxy: title: "Proxy pattern" - description: "A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate. In short, a proxy is a wrapper or agent object that is being called by the client to access the real serving object behind the scenes. Use of the proxy can simply be forwarding to the real object, or can provide additional logic. In the proxy extra functionality can be provided, for example caching when operations on the real object are resource intensive, or checking preconditions before operations on the real object are invoked. For the client, usage of a proxy object is similar to using the real object, because both implement the same interface." + description: "A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate. In short, a proxy is a wrapper or agent object that is being called by the client to access the real serving object behind the scenes. Use of the proxy can simply be forwarding to the real object, or can provide additional logic. In the proxy, extra functionality can be provided, for example, caching when operations on the real object are resource-intensive, or checking preconditions before operations on the real object are invoked. For the client, usage of a proxy object is similar to using the real object, because both implement the same interface." protection_proxy: title: "Protection proxy" - description: "Protection proxy. Are you working on an MNC? If so, we might be well aware of the proxy server that provides us internet by restricting access to some sort of websites like public e-mail, social networking, data storage etc. The management feels that, it is better to block some content and provide only work related web pages. Proxy server does that job. This is a type of proxy design pattern" + description: "Protection proxy: Are you working on an MNC? If so, we might be well aware of the proxy server that provides us internet by restricting access to some types of websites like public e-mail, social networking, data storage etc. The management feels that it is better to block some content and provide only work related web pages. A proxy server accomplishes this. This is a type of proxy design pattern." #English isn't as polished in this description as the others virtual_proxy: title: "Virtual proxy" - description: "Virtual proxy. In place of a complex or heavy object, use a skeleton representation. When an underlying image is huge in size, just represent it using a virtual proxy object and on-demand load the real object. You know that the real object is expensive in terms of instantiation and so without the real need we are not going to use the real object. Until the need arises we will use the virtual proxy." + description: "Virtual proxy: Uses a skeleton representation in place of a complex or heavy object. When an underlying image is huge in size, just represent it using a virtual proxy object and on-demand load the real object. You know that the real object is expensive in terms of instantiation, and so without a real need we are not going to use the real object. Until the need arises we will use the virtual proxy." #English isn't as polished in this description as the others remote_proxy: title: "Remote proxy" - description: "Remote proxy. In distributed object communication, a local object represents a remote object (one that belongs to a different address space). The local object is a proxy for the remote object, and method invocation on the local object results in remote method invocation on the remote object. Think of an ATM implementation, it will hold proxy objects for bank information that exists in the remote server." + description: "Remote proxy: In distributed object communication, a local object represents a remote object (one that belongs to a different address space). The local object is a proxy for the remote object, and method invocation on the local object results in remote method invocation on the remote object. Think of an ATM implementation: it will hold proxy objects for bank information that exists in the remote server." not_covered: title: "Not covered patterns:" callback: "Annotated Callback" @@ -347,7 +347,7 @@ pages: description: "In object-oriented design, the chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain." command: title: "Command pattern" - description: "The command pattern is a behavior design pattern used to store the information necessary to call methods at a future time. The command is merely a set of actions wrapped in an object. With ruby, we can use Procs to do the same thing without the need to create a separate object. This is a good option when the action is simple and doesn't require saving state information, otherwise, a command class is the better option." + description: "The command pattern is a behavioral design pattern used to store the information necessary to call methods at a future time. The command is merely a set of actions wrapped in an object. With ruby, we can use Procs to do the same thing without the need to create a separate object. This is a good option when the action is simple and doesn't require saving state information, otherwise, a command class is the better option." interpreter: title: "Interpreter pattern" description: "In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence for a client." @@ -356,28 +356,28 @@ pages: description: "The iterator design pattern provides sequential access to elements within a container without exposing how the container actually represents the elements. The iterator can be thought of as a movable pointer that allows access to elements encapsulated within a container." external_iterator: title: "External iterator pattern" - description: "External iterator: The iteration logic is contained in a separate class. The iteration class can be generalized to handle multiple object types as long as they allow indexing. It require the additional class to do the actual iterating, but they do allow for greater flexibility because you can control the iteration, which elements are iterated over and in what order." + description: "External iterator: The iteration logic is contained in a separate class. The iteration class can be generalized to handle multiple object types as long as they allow indexing. It requires the additional class to do the actual iterating, but it does allow for greater flexibility because you can control the iteration, which elements are iterated over, and in what order." internal_iterator: title: "Internal iterator pattern" - description: "Internal iterator: all the iterating logic occurs inside the aggregate object. Use a code block to pass your logic into the aggregate which then calls the block for each of it's elements." + description: "Internal iterator: All the iterating logic occurs inside the aggregate object. Use a code block to pass your logic into the aggregate, which then calls the block for each of its elements." mediator: title: "Mediator pattern" - description: "Usually a program is made up of a large number of classes. So the logic and computation is distributed among these classes. However, as more classes are developed in a program, especially during maintenance and / or refactoring, the problem of communication between these classes may become more complex. This makes the program harder to read and maintain. Furthermore, it can become difficult to change the program, since any change may affect code in several other classes. With the mediator pattern, communication between objects is encapsulated with a mediator object. Objects no longer communicate directly with each other, but instead communicate through the mediator. This reduces the dependencies between communicating objects, thereby lowering the coupling." + description: "Usually a program is made up of a large number of classes, which means the logic and computation is distributed among these classes. However, as more classes are developed in a program, especially during maintenance and / or refactoring, the problem of communication between these classes may become more complex. This makes the program harder to read and maintain. Furthermore, it can become difficult to change the program, since any change may affect code in several other classes. With the mediator pattern, communication between objects is encapsulated with a mediator object. Objects no longer communicate directly with each other, but instead communicate through the mediator. This reduces the dependencies between communicating objects, thereby lowering coupling." momento: title: "Momento pattern" - description: "The momento pattern is implemented with three objects: the originator, a caretaker and a momento. The originator is some object that has an internal state. The caretaker is going to do something to the originator, but wants to be able to undo the change. The caretaker first asks the originator for a momento object. Then it does whatever operation (or sequence of operations) it was going to do. To roll back to the state before the operations, it returns the momento object to the originator. The momento object itself is an opaque object (one which the caretaker cannot, or should not, change). When using this pattern, care should be taken if the originator may change other objects or resources - the momento pattern operates on a single object." + description: "The momento pattern is implemented with three objects: the originator, the caretaker, and the momento. The originator is some object that has an internal state. The caretaker is going to do something to the originator, but wants to be able to undo the change. The caretaker first asks the originator for a momento object. Then it does whatever operation (or sequence of operations) it was going to do. To roll back to the state before the operations, it returns the momento object to the originator. The momento object itself is an opaque object (one which the caretaker cannot, or should not, change). When using this pattern, care should be taken if the originator may change other objects or resources - the momento pattern operates on a single object." observer: title: "Observer pattern" - description: "The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems. The Observer pattern is also a key part in the familiar model–view–controller (MVC) architectural pattern. The observer pattern is implemented in numerous programming libraries and systems, including almost all GUI toolkits." + description: "The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event-handling systems. The Observer pattern is also a key part in the familiar model–view–controller (MVC) architectural pattern. The observer pattern is implemented in numerous programming libraries and systems, including almost all GUI toolkits." state: title: "State pattern" description: "The state pattern is a behavioral software design pattern that implements a state machine in an object-oriented way. With the state pattern, a state machine is implemented by implementing each individual state as a derived class of the state pattern interface, and implementing state transitions by invoking methods defined by the pattern's superclass." strategy: title: "Strategy pattern" - description: "Strategy lets the algorithm vary independently from clients that use it. Strategy is one of the patterns included in the influential book Design Patterns by Gamma et al. that popularized the concept of using patterns to describe software design. For instance, a class that performs validation on incoming data may use a strategy pattern to select a validation algorithm based on the type of data, the source of the data, user choice, or other discriminating factors. These factors are not known for each case until run-time, and may require radically different validation to be performed. The validation strategies, encapsulated separately from the validating object, may be used by other validating objects in different areas of the system (or even different systems) without code duplication." + description: "The strategy pattern lets the algorithm vary independently from clients that use it. Strategy is one of the patterns included in the influential book Design Patterns by Gamma et al. that popularized the concept of using patterns to describe software design. For instance, a class that performs validation on incoming data may use a strategy pattern to select a validation algorithm based on the type of data, the source of the data, user choice, or other discriminating factors. These factors are not known for each case until run-time, and may require radically different validation to be performed. The validation strategies, encapsulated separately from the validating object, may be used by other validating objects in different areas of the system (or even different systems) without code duplication." template: title: "Template method pattern" - description: "In object-oriented programming, first a class is created that provides the basic steps of an algorithm design. These steps are implemented using abstract methods. Later on, subclasses change the abstract methods to implement real actions. Thus the general algorithm is saved in one place but the concrete steps may be changed by the subclasses." + description: "In object-oriented programming, first, a class is created that provides the basic steps of an algorithm's design. These steps are implemented using abstract methods. Later on, subclasses change the abstract methods to implement real actions. Thus, the general algorithm is saved in one place, but the concrete steps may be changed by the subclasses." visitor: title: "Visitor pattern" description: "In object-oriented programming and software engineering, the visitor design pattern is a way of separating an algorithm from an object structure on which it operates. A practical result of this separation is the ability to add new operations to existing object structures without modifying those structures. It is one way to follow the open/closed principle. In essence, the visitor allows one to add new virtual functions to a family of classes without modifying the classes themselves; instead, one creates a visitor class that implements all of the appropriate specializations of the virtual function. The visitor takes the instance reference as input, and implements the goal through double dispatch." @@ -387,42 +387,42 @@ pages: credits: "Code and articles were taken from resources:" functional_programming: title: "Functional programming" - description: "Using a language in a functional style implies you have access to a few key features that listed below:" + description: "Using a language in a functional style implies you have access to a few key features that are listed below:" axioms: immutable: "Immutable values: once a “variable” is set, it cannot be changed. In Ruby, this means you effectively have to treat variables like constants." side_effects: "No side-effects: when passed a given value, a function must always return the same result. This goes hand in hand with having immutable values; a function can never take a value and change it, as this would be causing a side-effect that is tangential to returning a result." pure_functions: "Higher-order functions: these are functions that allow functions as arguments, or use functions as the return value. This is, arguably, one of the most critical features of any functional language." applying: "Currying: enabled by higher-order functions, currying is transforming a function that takes multiple arguments into a function that takes one argument. This goes hand in hand with partial function application, which is transforming a multi-argument function into a function that takes less arguments then it did originally." recursion: "Recursion: looping by calling a function from within itself. When you don’t have access to mutable data, recursion is used to build up and chain data construction. This is because looping is not a functional concept, as it requires variables to be passed around to store the state of the loop at a given time." - lazy: "Lazy-evaluation, or delayed-evaluation: delaying processing of values until the moment when it is actually needed. If, as an example, you have some code that generated list of Fibonacci numbers with lazy-evaluation enabled, this would not actually be processed and calculated until one of the values in the result was required by another function, such as puts." + lazy: "Lazy-evaluation, or delayed-evaluation: delaying processing of values until the moment when it is actually needed. If, as an example, you have some code that generated a list of Fibonacci numbers with lazy-evaluation enabled, this would not actually be processed and calculated until one of the values in the result was required by another function, such as puts." pure_functions: title: "Pure functions" description: "You can see that this function computes the result only using its arguments." closures: title: "Closures" - description: "Lambda's also enforce a closure and so are able to keep their context across objects." + description: "Lambda's also enforce a closure, and so are able to keep their context across objects." applying: title: "Partial applying and carrying" description: "Let’s first understand what these two different applications of functions are. Partial function application is calling a function with some number of arguments, in order to get a function back that will take that many fewer arguments. Currying is taking a function that takes n arguments, and splitting it into n functions that take one argument." - proc: "In order to give you a clearer idea of what each of these two things will do a function, let’s take an example Proc." + proc: "In order to give you a clearer idea of what each of these two things will do with a function, let’s take an example Proc." partial: "Partial application of this function would return, if we passed in the first two arguments, the following nested Procs." - curry: ".curry returns a curried proc. If the optional arity argument is given, it determines the number of arguments. A curried proc receives some arguments. If a sufficient number of arguments are supplied, it passes the supplied arguments to the original proc and returns the result. Otherwise, returns another curried proc that takes the rest of arguments." + curry: ".curry returns a curried proc. If the optional arity argument is given, it determines the number of arguments. A curried proc receives some arguments. If a sufficient number of arguments is supplied, it passes the supplied arguments to the original proc and returns the result. Otherwise, it returns another curried proc that takes the rest of the arguments." gotchas: title: "Gotchas" description1: "Most Ruby on Rails beginners get excited by the framework and start crafting applications without any knowledge of the language. And that’s the magic of RoR." - description2: "At some point things start to get serious. Some take time and effort to explore dirty secrets of Ruby on Rails, while others gloss over and become senior developers with almost zero knowledge of the language." - description3: "Anyway, sooner or later, beginners or experienced programmers, we all run into so-called Ruby Gotchas — those small language subtleties that hide from our site for hours of hardcore debugging." + description2: "At some point things start to get serious. Some take time and effort to explore the dirty secrets of Ruby on Rails, while others gloss over them and become senior developers with almost zero knowledge of the language." + description3: "Anyway, sooner or later, beginners or experienced programmers will all run into so-called Ruby Gotchas — those small language subtleties that hide from our sight during hours of hardcore debugging." description4: "Here is a list of popular Ruby gotchas and curiosities that developers should be aware of. For each case, there’s an example of confusing and/or error-prone code." - description5: "They come together with good practices, that will prevent you from making simple (but difficult to find) mistakes and simplify your (and your code maintainer’s) life." + description5: "They come together with good practices, that will prevent you from making simple (but difficult to find) mistakes and simplify your (and your code maintainer’s) life." #The grammar in this line isn't clear surprising: title: "Ruby can be surprising" - description: "Though \"engineered to maximize programmer happiness\", with the \"principle of least surprise\", Ruby still has gotchas. This presentation will proceed from newbie trivial gotchas, to more advanced and confusing gotchas." + description: "Though \"engineered to maximize programmer happiness\", with the \"principle of least surprise\", Ruby still has gotchas. This presentation will proceed from newbie trivial gotchas to more advanced and confusing gotchas." quotes: title: "Don't quote me on this, but..." - description: "String interpolation (including special chars like \\n) fails with 'single' quotes - it requires \"double\" quotes. Just like in most languages with string interpolation. To avoid it use doubles whenever practical." + description: "String interpolation (including special chars like \\n) fails with 'single' quotes - it requires \"double\" quotes. Just like in most languages with string interpolation. To avoid it, use double quotes whenever practical." twue: title: "It's twue! It's twue!" - description: "Only two things are false: false and nil. Everything else is truthy, even 0 (false in C), \"\" (false in JS), [], etc. Trips up people from C, JS, etc. where some of these are false." + description: "Only two things are false: false and nil. Everything else is truthy, even 0 (false in C), \"\" (false in JS), [], etc. Trips up people from C, JS, etc. where some of these are false." #Is truthy a word proper to Ruby? symbols_and_strings: title: "Hang him in effigy or String him up, symbolically." description: "Symbol != String. Even if the same when printed. Remember which one to use for args. Ideally, take either, and use what a method expects: \"Be liberal in what you accept, and conservative in what you send.\" Postel's Law." @@ -430,7 +430,7 @@ pages: title: "String... or nothing!" constants: title: "Constants Aren't" - description: "Initial uppercase means constant, in Ruby. Try to change a constant. Ooooh you get a WARNING! BFD. Even freezing doesn't work for Fixnums. It does work for arrays (sort of) and most other objects... he said foreshadowing." + description: "Initial uppercase means a constant in Ruby. Try to change a constant. Ooooh you get a WARNING! BFD. Even freezing doesn't work for Fixnums. It does work for arrays (sort of) and most other objects... he said foreshadowing." equals: title: "Some are more equal than others" description: "== is the usual same value, .eql? is value and class (1 is Fixnum, 1.0 is Float), .equal? is same object. It's actually much hairier." @@ -446,11 +446,11 @@ pages: usage: > With multiple args:
- - No parens, no problem. + - No parens, no problem. #Do you mean parens or parents?
- - Parents w/o space, OK. + - Parents w/o space, OK. #Do you mean parens or parents?
- - Parens and space, NO! + - Parens and space, NO! #Do you mean parens or parents? methods: "method /num is an unended regex or string! Ruby thinks you are giving an argument to the method. General principle: use BALANCED whitespace; both sides or neither." arguments: "one -2 makes Ruby think you are giving an argument -2 to method one. Same for +2 or even *2. Again: use BALANCED whitespace, both sides or neither." stubby: "\" Stabby\" lambdas (1.9+) Parentheses optional Space before after args without parents, OK. Space after parents, OK. Again, space before parents, NO! UPDATE: Fixed in 2.0!" @@ -468,7 +468,7 @@ pages: description: "super with no-arg list sends what caller got super with explicit args sends those args to send NO args, use empty parens: super()." regexp: title: "When will it end? (Or start?)" - description: "In standard regexps: ^ is start and $ is end of the whole string. Ruby’s regexes default to multiline, so: ^ is start and $ is end of any line! \\A is start and \\Z is end of the whole string. (Or \\z to include any newline… which is another gotcha!)" + description: "In standard regexps: ^ is the start and $ is the end of the whole string. Ruby’s regexes default to multiline, so: ^ is the start and $ is the end of any line! \\A is the start and \\Z is the end of the whole string. (Or \\z to include any newline… which is another gotcha!)" any: title: "getting .any?" description: ".any? does not mean \"any elements?\"! With block: \"do any make the block true?\". Without: \" are any truthy?\" Has implicit block: { |element| element }." @@ -480,38 +480,38 @@ pages: description: "Freezing an array (or a hash) freezes it, not the items it contains. Strings can be modified in place. This way, you can modify a given slot in a frozen Array of Strings." one_is_one: title: "1 is 1 … and ever more shall be so!" - description: "Changing Fixnum to new value means a new object. They can't be modified in place! So, can’t modify a frozen Array of Fixnums. (Fixnums and Integers have no bang-methods to demo trying with). BTW: a Fixnum's object_id is value * 2 + 1" + description: "Changing Fixnum to a new value means a new object. They can't be modified in place! So, can’t modify a frozen Array of Fixnums. (Fixnums and Integers have no bang-methods to demo trying with). BTW: a Fixnum's object_id is value * 2 + 1" bang: title: "(to! || ! to!) == ?" - description: "Bang marks the method as dangerous. Why? Often, may modify receiver, vs non-modding non-bang version. DO NOT RELY ON THEM RETURNING SAME VALUE AS NON-BANG VERSION! Many return nil if no change needed!" + description: "Bang marks the method as dangerous. Why? Often, may modify receiver, vs non-modding non-bang version. DO NOT RELY ON THEM RETURNING THE SAME VALUE AS NON-BANG VERSION! Many return null if no change needed!" array: title: "An Array of New Gotchas" description: "Default value given as object is the same object for each slot! Mutating one mutates default for all. Initial value given as block gets evaluated separately for each slot. Use this to create new vars for each." hash: title: "Making a Hash of it" - description: "Mostly the same problem (and solution) as Arrays. MORE GOTCHAS: creates a new object on any access to empty slot! May create an excessive number of new objects; ruins checking \"real\" contents or count (nil-checking, .size, etc.)." + description: "Mostly the same problem (and solution) as Arrays. MORE GOTCHAS: creates a new object on any access to empty slot! May create an excessive number of new objects; ruins checking \"real\" contents or count (null-checking, .size, etc.)." rescue: title: "Rescue Me, Throw a Line, I'll Try to Catch It!" description: "In Ruby, throw and catch are NOT for exceptions! They are advanced flow control, to exit deep nesting. Ruby uses raise and rescue for exceptions." to_str: title: "to_s VS to_str" - description: "to_s is defined on every object and will always return something. to_str is only defined on objects that are string-like. For example, Symbol has to_str but Array does not. Thus, you can use obj.respond_to?(:to_str) instead of something like obj.is_a?(String) if you want to take advantage of duck typing without worrying about whether the class you're working with is a subclass of String or not." + description: "to_s is defined on every object and will always return something. to_str is only defined on objects that are string-like. For example, Symbol has to_str but Array does not. Thus, you can use obj.respond_to?(:to_str) instead of something like obj.is_a?(String) if you want to take advantage of duct-taping without worrying about whether the class you're working with is a subclass of String or not." missing: title: "Need to coordinate method_missing and respond_to_missing?" description: "When overriding method_missing, remember to override respond_to_missing? as well. When you use method_missing to have an object return something on a method call, always make sure you also redefine respond_to_missing?. If you don't do it, nothing will break at a first glance, but you will run into trouble eventually. Consider this class:" respond_to: "Lots of code (gems or your own) relies on respond_to? (for a good reason). Do you need to patch respond_to_missing? as well:" exception: title: "rescue from a StandardError, not an Exception" - description: "Don't rescue Exception, rescue StandardError Before Explicitly rescuing Exception will rescue even not normally recoverable errors such as SyntaxError, LoadError, and Interrupt. If you omit the Exception type qualifier, then Ruby will catch only StandardError, which is probably what you want:" + description: "Don't rescue Exception, rescue StandardError Before Explicitly rescuing Exception will rescue even not normally recoverable errors such as SyntaxError, LoadError, and Interrupt. If you omit the Exception type qualifier, then Ruby will catch only StandardError, which is probably what you want:" private: title: "Private data isn’t really, and not at all w/ class methods" - description: "There’s a way to make class methods private in Ruby, you just gotta jump through some hoops. Err, I mean use the class << self syntax. This oddity pushes an instance singleton onto the class effectively creating class methods." + description: "There’s a way to make class methods private in Ruby, you just gotta jump through some hoops. Err, I mean use the class << self syntax. This oddity pushes an instance singleton onto the class, effectively creating class methods." braces: title: "Braces vs. do-end" description: "The general convention is to use do .. end for multi-line blocks and curly braces for single line blocks, but there is also a difference between the two that can be illustrated. This means that {} has a higher precedence than do .. end, so keep that in mind when deciding what you want to use." module: title: "class Foo::Bar, defined outside Module Foo, won’t see inside Foo" - description: "You can think of each appearance of module Something, class Something or def something as a \"gateway\" into a new scope. When Ruby is searching for the definition of a name that has been referenced it first looks in the current scope (the method, class or module), and if it isn’t found where it will go back through each containing \"gateway\" and search the scope there." + description: "You can think of each appearance of module Something, class Something or def something as a \"gateway\" into a new scope. When Ruby is searching for the definition of a name that has been referenced it first looks in the current scope (the method, class, or module), and if it isn’t found there, it will go back through each containing \"gateway\" and search the scope there." credits: "Code and articles were taken from resources:" meta_programming: title: "Metaprogramming" @@ -533,24 +533,24 @@ pages: good: "Good!" bad: "Bad!" title: "Solid principles" - description: "In computer programming, SOLID (single responsibility, Open-closed, Liskov substitution, interface segregation, and dependency inversion) is a mnemonic acronym introduced by Michael Feathers for the \"First Five Principles\" named by Robert C. Martin in the early 2000s that stands for five basic principles of object-oriented programming and design. The intention is that these principles, when applied together, will make it more likely that a programmer will create a system that is easy to maintain and extend over time. The principles of SOLID are guidelines that can be applied while working on software to remove code smells by causing the programmer to refactor the software's source code until it is both legible and extensible. It is part of an overall strategy of agile and Adaptive Software Development." + description: "In computer programming, SOLID (single responsibility, Open-closed, Liskov substitution, interface segregation, and dependency inversion) is a mnemonic acronym introduced by Michael Feathers for the \"First Five Principles\" named by Robert C. Martin in the early 2000s that stands for five basic principles of object-oriented programming and design. The intention is that these principles, when applied together, will make it more likely that a programmer will create a system that is easy to maintain and extend over time. The principles of SOLID are guidelines that can be applied while working on software to remove !code smells! by causing the programmer to refactor the software's source code until it is both legible and extensible. It is part of an overall strategy of agile and Adaptive Software Development." #What are code smells? single: title: "Single Responsibility Principle" - description: "The Single Responsibility Principle is the most abstract of the bunch. It helps keep classes and methods small and maintainable. In addition to keeping classes small and focused it also makes them easier to understand.An example of this might be adding support for sending an email summary of a specific person’s commissions after marking a deal processed. The fact that we can identify multiple reasons to change signals a violation of the Single Responsibility Principle." + description: "The Single Responsibility Principle is the most abstract of the bunch. It helps keep classes and methods small and maintainable. In addition to keeping classes small and focused, it also makes them easier to understand. An example of this might be adding support for sending an email summary of a specific person’s commissions after marking a deal processed. The fact that we can identify multiple reasons to change signals a violation of the Single Responsibility Principle." open_close: title: "Open / Closed Principle" - description: "The Open / Closed Principle states that classes or methods should be open for extension, but closed for modification. This tells us we should strive for modular designs that make it possible for us to change the behavior of the system without making modifications to the classes themselves. This is generally achieved through the use of patterns such as the strategy pattern." - after: "With this refactoring we’ve made it possible to add new parsers without changing any code. Any additional behavior will only require the addition of a new handler. This makes our FileParser reusable and in many cases will keep us in compliance with the Single Responsibility Principle as well by encouraging us to create smaller more focused classes." + description: "The Open / Closed Principle states that classes or methods should be open for extension, but closed for modification. This tells us we should strive for modular designs that make it possible for us to change the behavior of the system without making modifications to the classes themselves. This is generally achieved through the use of patterns, such as the strategy pattern." + after: "With this refactoring, we’ve made it possible to add new parsers without changing any code. Any additional behavior will only require the addition of a new handler. This makes our FileParser reusable and in many cases will keep us in compliance with the Single Responsibility Principle as well, by encouraging us to create smaller, more focused classes." liskov: title: "Liskov’s Substitution Principle" description: "Liskov’s principle tends to be the most difficult to understand. The principle states that you should be able to replace any instances of a parent class with an instance of one of its children without creating any unexpected or incorrect behaviors." segregation: title: "Dependency Inversion Principle" - description: "The principle states that a client should not be forced to depend on methods that it does not use. In this example, there are Computer, Programmer and Technician classes. Both Programmer and Technician use the Computer in a different way. The programmer uses the computer for typing, but the technician knows how to change the computer hard drive. What Interface Segregation Principle (ISP) enforces is that one class should not depend on methods it does not use. In our case, the Programmer is unnecessarily coupled to the Computer#change_hard_drive method because it does not use it, but the state changes that this method enforces can affect the Programmer. Let's refactor the code to obey the LSP." - after: "After this refactor the Technician uses a different object from the type ComputerInternals which is isolated from the state of the Computer. The state of the Computer object can be influenced by the Programmer but the changes won't affect the Technician in any way. " + description: "The principle states that a client should not be forced to depend on methods that it does not use. In this example, there are Computer, Programmer, and Technician classes. Both Programmer and Technician use the Computer in a different way. The programmer uses the computer for typing, but the technician knows how to change the computer hard drive. What Interface Segregation Principle (ISP) enforces is that one class should not depend on methods it does not use. In our case, the Programmer is unnecessarily coupled to the Computer#change_hard_drive method because it does not use it, but the state changes that this method enforces can affect the Programmer. Let's refactor the code to obey the LSP." + after: "After this refactor the Technician uses a different object from the type ComputerInternals which is isolated from the state of the Computer. The state of the Computer object can be influenced by the Programmer, but the changes won't affect the Technician in any way." di: title: "Dependency Inversion Principle" - description: "The Dependency Inversion Principle has to do with high-level (think business logic) objects not depending on low-level (think database querying and IO) implementation details. This can be achieved with duck typing and the Dependency Inversion Principle. Often this pattern is used to achieve the Open/Closed Principle that we discussed above. In fact, we can even reuse that same example as a demonstration of this principle. Now there is a formatter class, but I've hardcoded it on the Report class, thus creating a dependency from the Report to the JSONFormatter. Since the Report is a more abstract (high-level) concept than the JSONFormatter, we're effectively breaking the DIP." + description: "The Dependency Inversion Principle has to do with high-level (think business logic) objects not depending on low-level (think database querying and IO) implementation details. This can be achieved with duck typing and the Dependency Inversion Principle. Often, this pattern is used to achieve the Open/Closed Principle that we discussed above. In fact, we can even reuse that same example as a demonstration of this principle. Now there is a formatter class, but I've hardcoded it on the Report class, thus creating a dependency from the Report to the JSONFormatter. Since the Report is a more abstract (high-level) concept than the JSONFormatter, we're effectively breaking the DIP." after: "This way the Report does not depend on the JSONFormatter and can use any type of formatter that has a method called format (this is known as duck typing). Another thing of note is that we've used, once again, dependency injection to solve a problem. This technique is a very powerful one when our goal is decoupling objects, and even though it has the same initials as the dependency inversion principle (vs dependency injection pattern), they are completely different concepts." threads: example: "Example" @@ -561,40 +561,40 @@ pages: description: "Ruby 1.9 replaced green threads with native threads. However, the GIL is still preventing parallelism. That being said, concurrency has been improved through better scheduling. The new schedule makes context-switch decisions more efficient, by essentially moving them to a separate native thread, known as the timer thread." gil: title: "GIL - Global Interpreter Lock" - description: "MRI has a global interpreter lock (GIL). It's a lock around the execution of Ruby code. This means that in a multi-threaded context, only one thread can execute Ruby code at any one time.So if you have 8 threads busily working on an 8-core machine, only one thread and one core will be busy at any given time. The GIL exists to protect Ruby internals from race conditions that could corrupt data. There are caveats and optimizations, but this is the gist." - example: "This simple fact is what makes threads so powerful, and also what makes them difficult to work with. I've already given you an idea of why threads are good; here's a simple program to illustrate their difficulty. Here you can see that we have 10 * 10000 elements in array. Note that different ruby can show a different result. GIL exist only in MRI ruby." + description: "MRI has a global interpreter lock (GIL). It's a lock around the execution of Ruby code. This means that in a multi-threaded context, only one thread can execute Ruby code at any one time. So if you have 8 threads busily working on an 8-core machine, only one thread and one core will be busy at any given time. The GIL exists to protect Ruby internals from race conditions that could corrupt data. There are caveats and optimizations, but this is the gist." + example: "This simple fact is what makes threads so powerful, and also what makes them difficult to work with. I've already given you an idea of why threads are good; here's a simple program to illustrate their difficulty. Here you can see that we have 10 * 10000 elements in an array. Note that different ruby can show a different result. GIL exist only in MRI ruby." mutex: title: "Mutex - Mutual Execution" - description: "Mutexes provide a mechanism for multiple threads to synchronize access to a critical portion of code. In other words, they help bring some order, and some guarantees, to the world of multi-threaded chaos.The name 'mutex' is shorthand for 'mutual exclusion.' If you wrap some section of your code with a mutex, you guarantee that no two threads can enter that section at the same time. Mutexes provide a mechanism for multiple threads to synchronize access to a critical portion of code. It helps bring some order and some guaranty to the world of multi-threaded chaos." - example: "In this program, since any thread has to lock the mutex before it can push to the Array, there's a guarantee that no two threads will be performing this operation at the same time. In other words, this operation can no longer be interrupted before it's completed. Once one thread begins pushing to the Array, no other threads will be able to enter that portion of code until the first thread is finished. This operation is now thread-safe. Here you can see that we have 10 * 10000 elements in array. Now all are same, because of the mutex. The mutex sets up the same boundaries for the thread. The first thread that hits this bit of code will lock the mutex. it then becomes the owner of that mutex. Until the owning thread unlocks the mutex, no other thread can lock it." + description: "Mutexes provide a mechanism for multiple threads to synchronize access to a critical portion of code. In other words, they help bring some order, and some guarantees, to the world of multi-threaded chaos. The name 'mutex' is shorthand for 'mutual exclusion.' If you wrap some section of your code with a mutex, you guarantee that no two threads can enter that section at the same time. Mutexes provide a mechanism for multiple threads to synchronize access to a critical portion of code." #Deleted repitition in definition + example: "In this program, since any thread has to lock the mutex before it can push to the Array, there's a guarantee that no two threads will be performing this operation at the same time. In other words, this operation can no longer be interrupted before it's completed. Once one thread begins pushing to the Array, no other threads will be able to enter that portion of code until the first thread is finished. This operation is now thread-safe. Here you can see that we have 10 * 10000 elements in array. Now all are the same, because of the mutex. The mutex sets up the same boundaries for the thread. The first thread that hits this bit of code will lock the mutex. It then becomes the owner of that mutex. Until the owning thread unlocks the mutex, no other thread can lock it." fibers: title: "Fibers" - description: "Fibers are primitives for implementing light weight cooperative concurrency in Ruby. Basically, they are a means of creating code blocks that can be paused and resumed, much like threads. The main difference is that they are never preempted and that the scheduling must be done by the programmer and not the VM. As opposed to other stackless lightweight concurrency models, each fiber comes with a small 4KB stack. This enables the fiber to be paused from deeply nested function calls within the fiber block." + description: "Fibers are primitives for implementing lightweight cooperative concurrency in Ruby. Basically, they are a means of creating code blocks that can be paused and resumed, much like threads. The main difference is that they are never preempted and that the scheduling must be done by the programmer and not the VM. As opposed to other stackless lightweight concurrency models, each fiber comes with a small 4KB stack. This enables the fiber to be paused from deeply nested function calls within the fiber block." rails: title: "Rails thread-safety" - description: "The problem with this is that there is no simple way to say with absolute certainty whether an app as a whole is thread-safe. " + description: "The problem with this is that there is no simple way to say with absolute certainty whether an app as a whole is thread-safe." global_variables: "Global variables are global. This means that they are shared between threads. If you weren’t convinced about not using global variables by now, here’s another reason to never touch them. If you really want to share something globally across an app, you are more than likely better served by a constant (but see below), anyway." - class_variables: "Class variables. For the purpose of a discussion about threads, class variables are not much different from global variables. They are shared across threads just the same way.The problem isn’t so much about using class variables, but about mutating them. And if you are not going to mutate a class variable, in many cases a constant is again a better choice." - instance_variables: "Class instance variables. But maybe you’ve read that you should always use class instance variables instead of class variables in Ruby. Well, maybe you should, but they are just as problematic for threaded programs as class variables." - memoization: "Memoization by itself is not a thread safety issue. It is often used to store data in class variables or class instance variables (see the previous points). The ||= operator is, in fact, two operations, so there is a potential context switch happening in the middle of it, causing a race condition between threads. So even though you would only be using instance variables, you might end up with race conditions with memoization. Don’t memoize to class variables or class instance variables. If you need to memoize something on the class level, use thread local variables (Thread.current[:baz]) instead. Be aware, though, that it is still kind of a global variable." + class_variables: "Class variables: For the purpose of a discussion about threads, class variables are not much different from global variables. They are shared across threads just the same way. The problem isn’t so much about using class variables, but about mutating them. And if you are not going to mutate a class variable, in many cases a constant is again a better choice." + instance_variables: "Class instance variables: But maybe you’ve read that you should always use class instance variables instead of class variables in Ruby. Well, maybe you should, but they are just as problematic for threaded programs as class variables." + memoization: "Memoization by itself is not a thread-safety issue. It is often used to store data in class variables or class instance variables (see the previous points). The ||= operator is, in fact, two operations, so there is a potential context switch happening in the middle of it, causing a race condition between threads. So even though you would only be using instance variables, you might end up with race conditions with memoization. Don’t memoize to class variables or class instance variables. If you need to memoize something on the class level, use thread local variables (Thread.current[:baz]) instead. Be aware, though, that it is still kind of a global variable." #Do you mean it is a type of global variable, or that it is similar to a global variable? config: title: "Configure threadsafe!?" description: "Calling this method sets four options in our app configuration. Let’s walk through each option and talk about what it does." - frameworks: "Preloading Frameworks: The first option @preload_frameworks does pretty much what it says, it forces the Rails framework to be eagerly loaded on boot. When this option is not enabled, framework classes are loaded lazily via autoload. In multi-threaded environments, the framework needs to be eagerly loaded before any threads are created because of thread safety issues with autoload. We know that loading the framework isn’t threadsafe, so the strategy is to load it all up before any threads are ready to handle requests." - cache: "Caching classes: The @cache_classes option controls whether or not classes get reloaded. Remember when you’re doing “TDD” in your application? You modify a controller, then reload the page to “test” it and see that things changed? Ya, that’s what this option controls. When this option is false, as in development, your classes will be reloaded when they are modified. Without this option, we wouldn’t be able to do our “F5DD” (yes, that’s F5 Driven Development). In production, we know that classes aren’t going to be modified on the fly, so doing the work to figure out whether or not to reload classes is just wasting resources, so it makes sense to never reload class definitions." - di: "Dependency loading: This option, @dependency_loading controls code loading when missing constants are encountered. For example, a controller references the User model, but the User constant isn’t defined. In that case, if @dependency_loading is true, Rails will find the file that contains the User constant and load that file. We already talked about how code loading is not thread safe, so the idea here is that we should load the framework, then load all user code, then disable dependency loading. Once dependency loading is disabled, framework code and app code should be loaded, and any missing constants will just raise an exception rather than attempt to load code. We justify disabling this option in production because (as was mentioned earlier) code loading is not threadsafe, and we expect to have all code loaded before any threads can handle requests." - concurrency: "Allowing concurrency: @allow_concurrency option controls whether or not the Rack::Lock middleware is used in your stack. Rack::Lock wraps a mutex around your request. The idea being that if you have code that is not threadsafe, this mutex will prevent multiple threads from executing your controller code at the same time. When threadsafe! is set, this middleware is removed, and controller code can be executed in parallel." + frameworks: "Preloading Frameworks: The first option @preload_frameworks does pretty much what it says: it forces the Rails framework to be eagerly loaded on boot. When this option is not enabled, framework classes are loaded lazily via autoload. In multi-threaded environments, the framework needs to be eagerly loaded before any threads are created because of thread safety issues with autoload. We know that loading the framework isn’t threadsafe, so the strategy is to load it all up before any threads are ready to handle requests." + cache: "Caching classes: The @cache_classes option controls whether or not classes get reloaded. Remember when you’re doing “TDD” in your application? You modify a controller, then reload the page to “test” it and see that things changed? That's what this option controls. When this option is false, as in development, your classes will be reloaded when they are modified. Without this option, we wouldn’t be able to do our “F5DD” (yes, that’s F5 Driven Development). In production, we know that classes aren’t going to be modified on the fly, so doing the work to figure out whether or not to reload classes is just wasting resources. Therefore, it makes sense to never reload class definitions." + di: "Dependency loading: This option, @dependency_loading controls code loading when missing constants are encountered. For example, a controller references the User model, but the User constant isn’t defined. In that case, if @dependency_loading is true, Rails will find the file that contains the User constant and load that file. We already talked about how code loading is not thread safe, so the idea here is that we should load the framework, then load all the user code, then disable dependency loading. Once dependency loading is disabled, the framework code and the app code should be loaded, and any missing constants will just raise an exception rather than attempt to load code. We justify disabling this option in production because (as was mentioned earlier) code loading is not threadsafe, and we expect to have all code loaded before any threads can handle requests." + concurrency: "Allowing concurrency: The @allow_concurrency option controls whether or not the Rack::Lock middleware is used in your stack. Rack::Lock wraps a mutex around your request. The idea being that if you have code that is not threadsafe, this mutex will prevent multiple threads from executing your controller code at the same time. When threadsafe! is set, this middleware is removed, and controller code can be executed in parallel." credits: "Code and articles were taken from resources:" ruby_meister: - title: "Become Ruby Meister" - description: "In this talk, we'll examine the long journey from being a Ruby novice to achieving true Ruby mastery and will try to shorten it a bit for you by sharing some important insight. A Master Rubyist has a great theoretical foundation, relies on an extensive toolbox, has a deep understanding of the core values and principles of Ruby and is always honing their skills. Perhaps you're telling yourself \" Wow, this is pretty vague!\", but if you attend this session I promise that you'll be enlightened, amused and you'll totally enjoy it! Sounds good? The great books will be part of the resources I'd suggest to people to level-up their skills." + title: "Become Ruby Meister" #Do you mean Master? Meister could work, but it is slang + description: "In this talk, we'll examine the long journey from being a Ruby novice to achieving true Ruby mastery and will try to shorten it a bit for you by sharing some important insights. A Master Rubyist has a great theoretical foundation, relies on an extensive toolbox, has a deep understanding of the core values and principles of Ruby, and is always honing their skills. Perhaps you're telling yourself \" Wow, this is pretty vague!\", but if you attend this session, I promise that you'll be enlightened, amused, and you'll totally enjoy it! Sound good? Great books will be part of the resources I'll suggest to people to level-up their skills." video: "The Long Journey to Ruby Mastery by Bozhidar Batsov." computer_science_fundamentals: title: "Computer Science Fundamentals" articles: - name: 'inside_machine' title: "Inside the Machine: An Illustrated Introduction to Microprocessors and Computer Architecture" - description: "Computers perform countless tasks ranging from the business critical to the recreational, but regardless of how differently they may look and behave, they're all amazingly similar in basic function. Once you understand how the microprocessor—or central processing unit (CPU)—works, you'll have a firm grasp of the fundamental concepts at the heart of all modern computing." + description: "Computers perform countless tasks ranging from the business-critical to the recreational, but regardless of how differently they may look and behave, they're all amazingly similar in basic their basic functions. Once you understand how the microprocessor - or central processing unit (CPU) — works, you'll have a firm grasp of the fundamental concepts at the heart of all modern computing." link: "https://www.amazon.com/gp/product/1593271042/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1593271042&linkCode=as2&tag=khusnetdinov-20&linkId=f5f70df1b6ba3d39b4b114fe6dc617e1" - name: "code" title: "Code: The Hidden Language of Computer Hardware and Software" @@ -606,11 +606,11 @@ pages: link: "https://www.amazon.com/gp/product/0201558025/ref=as_li_tl?ie=UTF8&tag=khusnetdinov-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=0201558025&linkId=61e52e8b002ff4249fe1f16ab2a9f662" - name: "sicp" title: "Structure and Interpretation of Computer Programs" - description: "Structure and Interpretation of Computer Programs have had a dramatic impact on computer science curricula over the past decade. This long-awaited revision contains changes throughout the text. There are new implementations of most of the major programming systems in the book, including the interpreters and compilers, and the authors have incorporated many small changes that reflect their experience teaching the course at MIT since the first edition was published. A new theme has been introduced that emphasizes the central role played by different approaches to dealing with time in computational models: objects with state, concurrent programming, functional programming, and lazy evaluation, and nondeterministic programming." + description: "Structure and Interpretation of Computer Programs has had a dramatic impact on computer science curricula over the past decade. This long-awaited revision contains changes throughout the text. There are new implementations of most of the major programming systems in the book, including the interpreters and compilers, and the authors have incorporated many small changes that reflect their experience teaching the course at MIT since the first edition was published. A new theme has been introduced that emphasizes the central role played by different approaches to dealing with time in computational models: objects with state, concurrent programming, functional programming, lazy evaluation, and nondeterministic programming." link: "https://www.amazon.com/gp/product/0262510871/ref=as_li_tl?ie=UTF8&tag=khusnetdinov-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=0262510871&linkId=6e3898deeebdc0194f4f3604c09e84c4" - name: "design_programms" title: "How to Design Programs: An Introduction to Programming and Computing" - description: "This introduction to programming places computer science in the core of a liberal arts education. Unlike other introductory books, it focuses on the program design process. This approach fosters a variety of skills―critical reading, analytical thinking, creative synthesis, and attention to detail―that are important for everyone, not just future computer programmers. The book exposes readers to two fundamentally new ideas. First, it presents program design guidelines that show the reader how to analyze a problem statement; how to formulate concise goals; how to make up examples; how to develop an outline of the solution, based on the analysis; how to finish the program; and how to test." + description: "This introduction to programming places computer science in the core of a liberal arts education. Unlike other introductory books, it focuses on the program design process. This approach fosters a variety of skills―critical reading, analytical thinking, creative synthesis, and attention to detail that are important for everyone, not just future computer programmers. The book exposes readers to two fundamentally new ideas. First, it presents program design guidelines that show the reader how to analyze a problem statement; how to formulate concise goals; how to make up examples; how to develop an outline of the solution, based on the analysis; how to finish the program; and how to test." link: "https://www.amazon.com/gp/product/0262062186/ref=as_li_tl?ie=UTF8&tag=khusnetdinov-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=0262062186&linkId=1fa435d64a33dfa781508818d2579677" - name: "algorithm_manual" title: "The Algorithm Design Manual" @@ -622,11 +622,11 @@ pages: link: "https://www.amazon.com/gp/product/B07L5DG3K8/ref=as_li_tl?ie=UTF8&tag=khusnetdinov-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=B07L5DG3K8&linkId=6f3313f49a2a97c70b14bd735f7aed4d" - name: "compilers" title: "Compilers: Principles, Techniques, and Tools (2nd Edition)" - description: "Compilers: Principles, Techniques, and Tools, known to professors, students, and developers worldwide as the \"Dragon Book,\" is available in a new edition. Every chapter has been completely revised to reflect developments in software engineering, programming languages, and computer architecture that have occurred since 1986 when the last edition published. The authors, recognizing that few readers will ever go on to construct a compiler, retain their focus on the broader set of problems faced in software design and software development." + description: "Compilers: Principles, Techniques, and Tools, known to professors, students, and developers worldwide as the \"Dragon Book,\" is available in a new edition. Every chapter has been completely revised to reflect developments in software engineering, programming languages, and computer architecture that have occurred since 1986 when the last edition was published. The authors, recognizing that few readers will ever go on to construct a compiler, retain their focus on the broader set of problems faced in software design and software development." link: "https://www.amazon.com/gp/product/0321486811/ref=as_li_tl?ie=UTF8&tag=khusnetdinov-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=0321486811&linkId=0cf04c8a8e5d1290dc038d6461e2178e" - name: "c_lang" title: "C Programming Language, 2nd Edition" - description: "The authors present the complete guide to ANSI standard C language programming. Written by the developers of C, this new version helps readers keep up with the finalized ANSI standard for C while showing how to take advantage of C's rich set of operators, the economy of expression, improved control flow, and data structures. The 2/E has been completely rewritten with additional examples and problem sets to clarify the implementation of difficult language constructs. For years, C programmers have let K&R guide them to building well-structured and efficient programs. Now, this same help is available to those working with ANSI compilers. Includes detailed coverage of the C language plus the official C language reference manual for at-a-glance help with syntax notation, declarations, ANSI changes, scope rules, and the list goes on and on." + description: "The authors present the complete guide to ANSI standard C language programming. Written by the developers of C, this new version helps readers keep up with the finalized ANSI standard for C while showing how to take advantage of C's rich set of operators, the economy of expression, improved control flow, and data structures. The 2nd edition has been completely rewritten with additional examples and problem sets to clarify the implementation of difficult language constructs. For years, C programmers have let K&R guide them to building well-structured and efficient programs. Now, this same help is available to those working with ANSI compilers. Includes detailed coverage of the C language plus the official C language reference manual for at-a-glance help with syntax notation, declarations, ANSI changes, scope rules, and the list goes on and on." link: "https://www.amazon.com/gp/product/B07KS774TS/ref=as_li_tl?ie=UTF8&tag=khusnetdinov-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=B07KS774TS&linkId=5adab6fa324893f2fb0802f15593c2ca" oop: title: "Object-oriented programming" @@ -637,14 +637,14 @@ pages: link: "https://www.amazon.com/gp/product/B07L6HSHFB/ref=as_li_tl?ie=UTF8&tag=khusnetdinov-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=B07L6HSHFB&linkId=ea24df33da6c3ea5c32f34fe3848c3cc" - name: "domain_driven" title: "Domain-Driven Design: Tackling Complexity in the Heart of Software" - description: "This is a serious book about domain modeling in software design. Software development society lives from one hype wave to another. OOP, patterns, XP, TDD, CI/CD, BigData, DevOps - this is just to name a few. This book is originated from the golden age of OOP. The author admits that the object-oriented paradigm is not the only one available but the bias toward OOP/OOD is obvious (and justifiable). This book tells about how to do the modeling of core software components “the right way”." + description: "This is a serious book about domain modeling in software design. Software development society lives from one wave of hype to another. OOP, patterns, XP, TDD, CI/CD, BigData, DevOps - this is just to name a few. This book originated from the golden age of OOP. The author admits that the object-oriented paradigm is not the only one available but the bias toward OOP/OOD is obvious (and justifiable). This book tells about how to do the modeling of core software components “the right way”." link: "https://www.amazon.com/gp/product/8131724468/ref=as_li_tl?ie=UTF8&tag=khusnetdinov-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=8131724468&linkId=8c60c936dfb1dbd0ffa827cdeca40983" ruby: title: "Know you lang" articles: - name: "well_grounded" title: "The Well-Grounded Rubyist" - description: "The Well-Grounded Rubyist, Second Edition addresses both newcomers to Ruby as well as Ruby programmers who want to deepen their understanding of the language. This beautifully written and totally revised second edition includes coverage of features that are new in Ruby 2.1, as well as expanded and updated coverage of aspects of the language that have changed." + description: "The Well-Grounded Rubyist, Second Edition, addresses both newcomers to Ruby, as well as Ruby programmers who want to deepen their understanding of the language. This beautifully written and totally revised second edition includes coverage of features that are new in Ruby 2.1, as well as expanded and updated coverage of aspects of the language that have changed." link: "https://www.amazon.com/gp/product/B07L6JSF39/ref=as_li_tl?ie=UTF8&tag=khusnetdinov-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=B07L6JSF39&linkId=b2cc9624cf7470cc171fd7ecf99ba334" - name: "programming_ruby" title: "Programming Ruby: The Pragmatic Programmers Guide, Second Edition" @@ -652,11 +652,11 @@ pages: link: "https://www.amazon.com/gp/product/0974514055/ref=as_li_tl?ie=UTF8&tag=khusnetdinov-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=0974514055&linkId=40970dcd1f5538a268c6b9b272bb2f30" - name: "ruby_programming" title: "The Ruby Programming Language: Everything You Need to Know" - description: "This book begins with a quick-start tutorial to the language, and then explains the language in detail from the bottom up: from lexical and syntactic structure to datatypes to expressions and statements and on through methods, blocks, lambdas, closures, classes, and modules. The book also includes a long and thorough introduction to the rich API of the Ruby platform, demonstrating -- with heavily-commented example code -- Ruby's facilities for text processing, numeric manipulation, collections, input/output, networking, and concurrency. An entire chapter is devoted to Ruby's metaprogramming capabilities." + description: "This book begins with a quick-start tutorial of the language, and then explains the language in detail from the bottom up: from lexical and syntactic structure, to datatypes, to expressions and statements, and on through methods, blocks, lambdas, closures, classes, and modules. The book also includes a long and thorough introduction to the rich API of the Ruby platform, demonstrating -- with heavily-commented example code -- Ruby's facilities for text processing, numeric manipulation, collections, input/output, networking, and concurrency. An entire chapter is devoted to Ruby's metaprogramming capabilities." link: "https://www.amazon.com/gp/product/0596516177/ref=as_li_tl?ie=UTF8&tag=khusnetdinov-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=0596516177&linkId=3945be310f5732d57ef39dfb3ebdd4b8" interview_questions: title: "Interview questions" - description: "This section keeps resources links for reading and interview preparation" + description: "This section keeps resource links for reading and interview preparation" list: - name: "Toptal: How to Hire a Great Ruby Developer" link: "https://www.toptal.com/ruby#hiring-guide" @@ -674,8 +674,8 @@ pages: link: "https://www.toptal.com/ruby-on-rails/interview-questions" index: title: "What is Better Docs" - description: "This website is web adaptation Github repository Ruby.Fundamental which collected a lot of stars and was translated into the Chinese language. Better Docs allow you to quickly find a lot of best practice that was collected in one repository. Just use this repo like the reference or interview preparation resource." + description: "This website is a web adaptation Github repository Ruby.Fundamental which collected a lot of stars and was translated into the Chinese language. Better Docs allows you to quickly find a lot of best practice that was collected in one repository. Just use this repo like the reference or interview preparation resource." oss: title: "Thanks to Open Source" - description: "Better Docs was created while working and finding out about best practices and knowledge about ruby, an open source engineering for the web development applications written in Ruby." + description: "Better Docs was created while working and finding out about best practices and knowledge about ruby, an open source engineering for the web development applications written in Ruby." #Not sure what the 2nd half of the sentence (after the comma) is referring to thanks: "If Better Docs helped you in any way, think about giving us a Star on Github (it helps us to reach more developers) or contributing to our projects." From 1b80376e7457b6b0f4c414c2c40d569072207ad4 Mon Sep 17 00:00:00 2001 From: TantumErgo <9907196+TantumErgo@users.noreply.github.com> Date: Thu, 5 Sep 2019 15:29:53 -0400 Subject: [PATCH 2/2] More edits of typos, grammatical errors Checked all edits made in the first run-through. Ready for pull request. --- _i18n/en.yml | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/_i18n/en.yml b/_i18n/en.yml index 25c57d9..ce2bf85 100644 --- a/_i18n/en.yml +++ b/_i18n/en.yml @@ -92,7 +92,7 @@ sidebar: submenus: - surprising - quotes - - twue #What is this word? + - twue #Is this a Ruby word? - symbols_and_strings - string_or_nothing - constants @@ -132,9 +132,9 @@ sidebar: submenus: - single - open_close - - liskov #What is this word? Seems to be incorrect translation + - liskov - segregation - - di #What does this mean? + - di - title: "Become Ruby Meister" #Do you mean Become Ruby MASTER, or do you mean Meister? Master would be better English, Meister is made-up slang url: ruby_meister #See comment on line 138 - title: Threads @@ -175,7 +175,7 @@ pages: description: "From the comparison presented here, one might conclude that selection sort should never be used. It does not adapt to the data in any way (notice that the four animations above run in lockstep), so its runtime is always quadratic. However, selection sort has the property of minimizing the number of swaps. In applications where the cost of swapping items is high, selection sort very well may be the algorithm of choice." shell_sort: title: "Shell sort" - description: "The worst-case time complexity of shell sort depends on the increment sequence. For the increments 1 4 13 40 121 ..., which is what is used here, the time complexity is O(n32). For other increments, time complexity is known to be O(n43) and even O(n·lg2(n)). Neither the tight upper bounds on the time complexity nor the best increment sequence is known. Because shell sort is based on insertion sort, shell sort inherits insertion sort’s adaptive properties. The adaptation is not as dramatic, because shell sort requires one pass through the data for each increment, but it is significant. For the increment sequence shown above, there are log3(n) increments, so the time complexity for nearly-sorted data is O(n·log3(n)). Because of its low overhead, relatively simple implementation, adaptive properties, and sub-quadratic time complexity, shell sort may be a viable alternative to the O(n·lg(n)) sorting algorithms for some applications when the data to be sorted is not very large." + description: "The worst-case time complexity of shell sort depends on the increment sequence. For the increments 1 4 13 40 121 ..., which is what is used here, the time complexity is O(n32). For other increments, time complexity is known to be O(n43) and even O(n·lg2(n)). Neither the tight upper bounds on the time complexity nor the best increment sequence is known. Because shell sort is based on insertion sort, shell sort inherits insertion sort’s adaptive properties. The adaptation is not as dramatic, because shell sort requires one pass through the data for each increment, but it is significant. For the increment sequence shown above, there are log3(n) increments, so the time complexity for nearly-sorted data is O(n·log3(n)). Because of its low overhead, relatively simple implementation, adaptive properties, and sub-quadratic time complexity, shell sort may be a viable alternative to the O(n·lg(n)) sorting algorithms for some applications, when the data to be sorted is not very large." heap_sort: title: "Heap sort" description: "Heap sort is simple to implement, performs an O(n·lg(n)) in-place sort, but is not stable. The first loop, the Θ(n) “heapify” phase, puts the array into heap order. The second loop, the O(n·lg(n)) “sort down” phase, repeatedly extracts the maximum and restores heap order. The sink function is written recursively for clarity. Thus, as shown, the code requires Θ(lg(n)) space for the recursive call stack. However, the tail recursion in sink() is easily converted to iteration, which yields the O(1) space bound. Both phases are slightly adaptive, though not in any particularly useful manner. In the nearly-sorted case, the heapify phase destroys the original order. In the reversed case, the heapify phase is as fast as possible, since the array starts in heap order, but then the sort down phase is typical. In the few unique keys case, there is some speedup, but not as much as in shell sort or 3-way quicksort." @@ -242,7 +242,7 @@ pages: as_linked_list: "Stack as linked list" queue: title: "Queue" - description: "A queue is a simple container-based structure that mimics a real-life queue (e.g. waiting in line at the bank). It is FIFO (first-in-first-out), meaning that when you retrieve items from the queue, they are returned in the order in which they entered. Ruby Arrays provide methods that make Queue implementation trivially easy, but having them named appropriately and contained in a convenience class #is worth it to see they are implemented, and because other structures will inherit from this one.# An alternate implementation could be done using a linked list." #The text between the two #'s doesn't make clear sense. What is the meaning you want to say? + description: "A queue is a simple container-based structure that mimics a real-life queue (e.g. waiting in line at the bank). It is FIFO (first-in-first-out), meaning that when you retrieve items from the queue, they are returned in the order in which they entered. Ruby Arrays provide methods that make Queue implementation trivially easy, but having them named appropriately and contained in a convenience class !is worth it to see they are implemented, and because other structures will inherit from this one.! An alternate implementation could be done using a linked list." #The text between the two !'s doesn't make clear sense. What is the meaning you want to say? as_array: "Queue as array" as_linked_list: "Queue as linked list" deque: @@ -293,7 +293,7 @@ pages: description: "In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method (either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes) rather than by calling a constructor." prototype: title: "Prototype pattern" - description: "The prototype pattern is a creational pattern along the lines of the factory pattern. The trick with the prototype is that you create new objects by copying a master object. Changes to that master object and all subsequent objects that you create !will go off into life! with a copy of the change." #Return here to fix the bounded part + description: "The prototype pattern is a creational pattern along the lines of the factory pattern. The trick with the prototype is that you create new objects by copying a master object. Changes to that master object and all subsequent objects that you create !will go off into life! with a copy of the change." #Phrase between the !'s is not very good English. What do you mean to say? singleton: title: "Singleton pattern" description: "Ensures a class only has one instance, and provides a global point of access to it. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects." @@ -347,7 +347,7 @@ pages: description: "In object-oriented design, the chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain." command: title: "Command pattern" - description: "The command pattern is a behavioral design pattern used to store the information necessary to call methods at a future time. The command is merely a set of actions wrapped in an object. With ruby, we can use Procs to do the same thing without the need to create a separate object. This is a good option when the action is simple and doesn't require saving state information, otherwise, a command class is the better option." + description: "The command pattern is a behavioral design pattern used to store the information necessary to call methods at a future time. The command is merely a set of actions wrapped in an object. With Ruby, we can use Procs to do the same thing without the need to create a separate object. This is a good option when the action is simple and doesn't require saving state information, otherwise, a command class is the better option." interpreter: title: "Interpreter pattern" description: "In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence for a client." @@ -430,7 +430,7 @@ pages: title: "String... or nothing!" constants: title: "Constants Aren't" - description: "Initial uppercase means a constant in Ruby. Try to change a constant. Ooooh you get a WARNING! BFD. Even freezing doesn't work for Fixnums. It does work for arrays (sort of) and most other objects... he said foreshadowing." + description: "Initial uppercase means a constant in Ruby. Try to change a constant. Ooooh you get a WARNING! BFD. Even freezing doesn't work for Fixnums. It does work for arrays (sort of) and most other objects... he said foreshadowing." #English is very difficult to understand in this line equals: title: "Some are more equal than others" description: "== is the usual same value, .eql? is value and class (1 is Fixnum, 1.0 is Float), .equal? is same object. It's actually much hairier." @@ -483,7 +483,7 @@ pages: description: "Changing Fixnum to a new value means a new object. They can't be modified in place! So, can’t modify a frozen Array of Fixnums. (Fixnums and Integers have no bang-methods to demo trying with). BTW: a Fixnum's object_id is value * 2 + 1" bang: title: "(to! || ! to!) == ?" - description: "Bang marks the method as dangerous. Why? Often, may modify receiver, vs non-modding non-bang version. DO NOT RELY ON THEM RETURNING THE SAME VALUE AS NON-BANG VERSION! Many return null if no change needed!" + description: "Bang marks the method as dangerous. Why? Often, may modify receiver, vs non-modding non-bang version. DO NOT RELY ON THEM RETURNING THE SAME VALUE AS NON-BANG VERSION! Many return null if no change needed!" #English not very clear in this line array: title: "An Array of New Gotchas" description: "Default value given as object is the same object for each slot! Mutating one mutates default for all. Initial value given as block gets evaluated separately for each slot. Use this to create new vars for each." @@ -495,7 +495,7 @@ pages: description: "In Ruby, throw and catch are NOT for exceptions! They are advanced flow control, to exit deep nesting. Ruby uses raise and rescue for exceptions." to_str: title: "to_s VS to_str" - description: "to_s is defined on every object and will always return something. to_str is only defined on objects that are string-like. For example, Symbol has to_str but Array does not. Thus, you can use obj.respond_to?(:to_str) instead of something like obj.is_a?(String) if you want to take advantage of duct-taping without worrying about whether the class you're working with is a subclass of String or not." + description: "to_s is defined on every object and will always return something. to_str is only defined on objects that are string-like. For example, Symbol has to_str but Array does not. Thus, you can use obj.respond_to?(:to_str) instead of something like obj.is_a?(String) if you want to take advantage of duck typing without worrying about whether the class you're working with is a subclass of String or not." missing: title: "Need to coordinate method_missing and respond_to_missing?" description: "When overriding method_missing, remember to override respond_to_missing? as well. When you use method_missing to have an object return something on a method call, always make sure you also redefine respond_to_missing?. If you don't do it, nothing will break at a first glance, but you will run into trouble eventually. Consider this class:" @@ -511,7 +511,7 @@ pages: description: "The general convention is to use do .. end for multi-line blocks and curly braces for single line blocks, but there is also a difference between the two that can be illustrated. This means that {} has a higher precedence than do .. end, so keep that in mind when deciding what you want to use." module: title: "class Foo::Bar, defined outside Module Foo, won’t see inside Foo" - description: "You can think of each appearance of module Something, class Something or def something as a \"gateway\" into a new scope. When Ruby is searching for the definition of a name that has been referenced it first looks in the current scope (the method, class, or module), and if it isn’t found there, it will go back through each containing \"gateway\" and search the scope there." + description: "You can think of each appearance of module Something, class Something or def something as a \"gateway\" into a new scope. When Ruby is searching for the definition of a name that has been referenced, it first looks in the current scope (the method, class, or module), and if it isn’t found there, it will go back through each containing \"gateway\" and search the scope there." credits: "Code and articles were taken from resources:" meta_programming: title: "Metaprogramming" @@ -547,7 +547,7 @@ pages: segregation: title: "Dependency Inversion Principle" description: "The principle states that a client should not be forced to depend on methods that it does not use. In this example, there are Computer, Programmer, and Technician classes. Both Programmer and Technician use the Computer in a different way. The programmer uses the computer for typing, but the technician knows how to change the computer hard drive. What Interface Segregation Principle (ISP) enforces is that one class should not depend on methods it does not use. In our case, the Programmer is unnecessarily coupled to the Computer#change_hard_drive method because it does not use it, but the state changes that this method enforces can affect the Programmer. Let's refactor the code to obey the LSP." - after: "After this refactor the Technician uses a different object from the type ComputerInternals which is isolated from the state of the Computer. The state of the Computer object can be influenced by the Programmer, but the changes won't affect the Technician in any way." + after: "After this refactor, the Technician uses a different object from the type ComputerInternals which is isolated from the state of the Computer. The state of the Computer object can be influenced by the Programmer, but the changes won't affect the Technician in any way." di: title: "Dependency Inversion Principle" description: "The Dependency Inversion Principle has to do with high-level (think business logic) objects not depending on low-level (think database querying and IO) implementation details. This can be achieved with duck typing and the Dependency Inversion Principle. Often, this pattern is used to achieve the Open/Closed Principle that we discussed above. In fact, we can even reuse that same example as a demonstration of this principle. Now there is a formatter class, but I've hardcoded it on the Report class, thus creating a dependency from the Report to the JSONFormatter. Since the Report is a more abstract (high-level) concept than the JSONFormatter, we're effectively breaking the DIP." @@ -562,7 +562,7 @@ pages: gil: title: "GIL - Global Interpreter Lock" description: "MRI has a global interpreter lock (GIL). It's a lock around the execution of Ruby code. This means that in a multi-threaded context, only one thread can execute Ruby code at any one time. So if you have 8 threads busily working on an 8-core machine, only one thread and one core will be busy at any given time. The GIL exists to protect Ruby internals from race conditions that could corrupt data. There are caveats and optimizations, but this is the gist." - example: "This simple fact is what makes threads so powerful, and also what makes them difficult to work with. I've already given you an idea of why threads are good; here's a simple program to illustrate their difficulty. Here you can see that we have 10 * 10000 elements in an array. Note that different ruby can show a different result. GIL exist only in MRI ruby." + example: "This simple fact is what makes threads so powerful, and also what makes them difficult to work with. I've already given you an idea of why threads are good; here's a simple program to illustrate their difficulty. Here you can see that we have 10 * 10000 elements in an array. Note that different Ruby can show a different result. GIL exist only in MRI Ruby." mutex: title: "Mutex - Mutual Execution" description: "Mutexes provide a mechanism for multiple threads to synchronize access to a critical portion of code. In other words, they help bring some order, and some guarantees, to the world of multi-threaded chaos. The name 'mutex' is shorthand for 'mutual exclusion.' If you wrap some section of your code with a mutex, you guarantee that no two threads can enter that section at the same time. Mutexes provide a mechanism for multiple threads to synchronize access to a critical portion of code." #Deleted repitition in definition @@ -587,14 +587,14 @@ pages: credits: "Code and articles were taken from resources:" ruby_meister: title: "Become Ruby Meister" #Do you mean Master? Meister could work, but it is slang - description: "In this talk, we'll examine the long journey from being a Ruby novice to achieving true Ruby mastery and will try to shorten it a bit for you by sharing some important insights. A Master Rubyist has a great theoretical foundation, relies on an extensive toolbox, has a deep understanding of the core values and principles of Ruby, and is always honing their skills. Perhaps you're telling yourself \" Wow, this is pretty vague!\", but if you attend this session, I promise that you'll be enlightened, amused, and you'll totally enjoy it! Sound good? Great books will be part of the resources I'll suggest to people to level-up their skills." + description: "In this talk, we'll examine the long journey from being a Ruby novice to achieving true Ruby mastery and will try to shorten it a bit for you by sharing some important insights. Master Rubyists have a great theoretical foundation, rely on an extensive toolbox, have a deep understanding of the core values and principles of Ruby, and are always honing their skills. Perhaps you're telling yourself \" Wow, this is pretty vague!\", but if you attend this session, I promise that you'll be enlightened, amused, and you'll totally enjoy it! Sound good? Great books will be part of the resources I'll suggest to people to level-up their skills." video: "The Long Journey to Ruby Mastery by Bozhidar Batsov." computer_science_fundamentals: title: "Computer Science Fundamentals" articles: - name: 'inside_machine' title: "Inside the Machine: An Illustrated Introduction to Microprocessors and Computer Architecture" - description: "Computers perform countless tasks ranging from the business-critical to the recreational, but regardless of how differently they may look and behave, they're all amazingly similar in basic their basic functions. Once you understand how the microprocessor - or central processing unit (CPU) — works, you'll have a firm grasp of the fundamental concepts at the heart of all modern computing." + description: "Computers perform countless tasks ranging from the business-critical to the recreational, but regardless of how differently they may look and behave, they're all amazingly similar in their basic functions. Once you understand how the microprocessor - or central processing unit (CPU) — works, you'll have a firm grasp of the fundamental concepts at the heart of all modern computing." link: "https://www.amazon.com/gp/product/1593271042/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1593271042&linkCode=as2&tag=khusnetdinov-20&linkId=f5f70df1b6ba3d39b4b114fe6dc617e1" - name: "code" title: "Code: The Hidden Language of Computer Hardware and Software" @@ -610,7 +610,7 @@ pages: link: "https://www.amazon.com/gp/product/0262510871/ref=as_li_tl?ie=UTF8&tag=khusnetdinov-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=0262510871&linkId=6e3898deeebdc0194f4f3604c09e84c4" - name: "design_programms" title: "How to Design Programs: An Introduction to Programming and Computing" - description: "This introduction to programming places computer science in the core of a liberal arts education. Unlike other introductory books, it focuses on the program design process. This approach fosters a variety of skills―critical reading, analytical thinking, creative synthesis, and attention to detail that are important for everyone, not just future computer programmers. The book exposes readers to two fundamentally new ideas. First, it presents program design guidelines that show the reader how to analyze a problem statement; how to formulate concise goals; how to make up examples; how to develop an outline of the solution, based on the analysis; how to finish the program; and how to test." + description: "This introduction to programming places computer science in the core of a liberal arts education. Unlike other introductory books, it focuses on the program design process. This approach fosters a variety of skills (critical reading, analytical thinking, creative synthesis, and attention to detail) that are important for everyone, not just future computer programmers. The book exposes readers to two fundamentally new ideas. First, it presents program design guidelines that show the reader how to analyze a problem statement; how to formulate concise goals; how to make up examples; how to develop an outline of the solution, based on the analysis; how to finish the program; and how to test." link: "https://www.amazon.com/gp/product/0262062186/ref=as_li_tl?ie=UTF8&tag=khusnetdinov-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=0262062186&linkId=1fa435d64a33dfa781508818d2579677" - name: "algorithm_manual" title: "The Algorithm Design Manual" @@ -637,7 +637,7 @@ pages: link: "https://www.amazon.com/gp/product/B07L6HSHFB/ref=as_li_tl?ie=UTF8&tag=khusnetdinov-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=B07L6HSHFB&linkId=ea24df33da6c3ea5c32f34fe3848c3cc" - name: "domain_driven" title: "Domain-Driven Design: Tackling Complexity in the Heart of Software" - description: "This is a serious book about domain modeling in software design. Software development society lives from one wave of hype to another. OOP, patterns, XP, TDD, CI/CD, BigData, DevOps - this is just to name a few. This book originated from the golden age of OOP. The author admits that the object-oriented paradigm is not the only one available but the bias toward OOP/OOD is obvious (and justifiable). This book tells about how to do the modeling of core software components “the right way”." + description: "This is a serious book about domain modeling in software design. Software development society lives from one wave of hype to another. OOP, patterns, XP, TDD, CI/CD, BigData, DevOps - this is just to name a few. This book originated from the golden age of OOP. The author admits that the object-oriented paradigm is not the only one available, but the bias toward OOP/OOD is obvious (and justifiable). This book tells about how to do the modeling of core software components “the right way”." link: "https://www.amazon.com/gp/product/8131724468/ref=as_li_tl?ie=UTF8&tag=khusnetdinov-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=8131724468&linkId=8c60c936dfb1dbd0ffa827cdeca40983" ruby: title: "Know you lang" @@ -674,8 +674,8 @@ pages: link: "https://www.toptal.com/ruby-on-rails/interview-questions" index: title: "What is Better Docs" - description: "This website is a web adaptation Github repository Ruby.Fundamental which collected a lot of stars and was translated into the Chinese language. Better Docs allows you to quickly find a lot of best practice that was collected in one repository. Just use this repo like the reference or interview preparation resource." + description: "This website is a web adaptation Github repository Ruby.Fundamental which collected a lot of stars and was translated into the Chinese language. Better Docs allows you to quickly find a lot of best practices collected into one repository. Just use this repo like the reference or interview preparation resource." oss: title: "Thanks to Open Source" - description: "Better Docs was created while working and finding out about best practices and knowledge about ruby, an open source engineering for the web development applications written in Ruby." #Not sure what the 2nd half of the sentence (after the comma) is referring to + description: "Better Docs was created while working and finding out about best practices and knowledge about Ruby, an open source engineering for the web development applications written in Ruby." #Not sure what the 2nd half of the sentence (after the comma) is referring to thanks: "If Better Docs helped you in any way, think about giving us a Star on Github (it helps us to reach more developers) or contributing to our projects."