dnrops.gitlink.net/posts/ruby/learn_ruby.html

603 lines
46 KiB
HTML

<!DOCTYPE HTML>
<html lang="en" class="coal" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>learn ruby - Andrew&#x27;s Blog</title>
<!-- Custom HTML head -->
<meta name="description" content="Andrew Ryan&#x27;s Blog">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="../../favicon.svg">
<link rel="shortcut icon" href="../../favicon.png">
<link rel="stylesheet" href="../../css/variables.css">
<link rel="stylesheet" href="../../css/general.css">
<link rel="stylesheet" href="../../css/chrome.css">
<!-- Fonts -->
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../../highlight.css">
<link rel="stylesheet" href="../../tomorrow-night.css">
<link rel="stylesheet" href="../../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="../../src/style/custom.css">
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "../../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "coal" : "coal";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('coal')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item affix "><a href="../../index.html">Andrew's Blog</a></li><li class="chapter-item "><a href="../../posts/linux/linux.html"><strong aria-hidden="true">1.</strong> linux</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/linux/install_linux.html"><strong aria-hidden="true">1.1.</strong> install linux</a></li><li class="chapter-item "><a href="../../posts/linux/bash_profile.html"><strong aria-hidden="true">1.2.</strong> bash profile</a></li><li class="chapter-item "><a href="../../posts/linux/command_list.html"><strong aria-hidden="true">1.3.</strong> command list</a></li><li class="chapter-item "><a href="../../posts/linux/git_guide.html"><strong aria-hidden="true">1.4.</strong> git guide</a></li><li class="chapter-item "><a href="../../posts/linux/tar.html"><strong aria-hidden="true">1.5.</strong> tar</a></li><li class="chapter-item "><a href="../../posts/linux/run_x86_elf_in_x64_setup.html"><strong aria-hidden="true">1.6.</strong> run x86 elf in x64 setup</a></li></ol></li><li class="chapter-item "><a href="../../posts/mac/mac.html"><strong aria-hidden="true">2.</strong> mac</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/mac/macos_profiles.html"><strong aria-hidden="true">2.1.</strong> macos profiles</a></li></ol></li><li class="chapter-item "><a href="../../posts/swift/swift.html"><strong aria-hidden="true">3.</strong> swift</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/swift/learn_swift.html"><strong aria-hidden="true">3.1.</strong> learn swift basics</a></li><li class="chapter-item "><a href="../../posts/swift/swift_extensions.html"><strong aria-hidden="true">3.2.</strong> Swift extensions</a></li><li class="chapter-item "><a href="../../posts/swift/swiftui_extension.html"><strong aria-hidden="true">3.3.</strong> SwiftUI extensions</a></li><li class="chapter-item "><a href="../../posts/swift/install_swift.html"><strong aria-hidden="true">3.4.</strong> install swift</a></li><li class="chapter-item "><a href="../../posts/swift/task_planner.html"><strong aria-hidden="true">3.5.</strong> implment task panner app with SwiftUI</a></li><li class="chapter-item "><a href="../../posts/swift/swift_cheat_sheet.html"><strong aria-hidden="true">3.6.</strong> Swift Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/swift/yinci_url.html"><strong aria-hidden="true">3.7.</strong> Personal privacy protocol</a></li><li class="chapter-item "><a href="../../posts/swift/swift_regular_exressions.html"><strong aria-hidden="true">3.8.</strong> Swift regular exressions</a></li><li class="chapter-item "><a href="../../posts/ios/how_to_create_beautiful_ios_charts_in_swift.html"><strong aria-hidden="true">3.9.</strong> How to Create Beautiful iOS Charts in鑱絊wift</a></li><li class="chapter-item "><a href="../../posts/swift/swiftui_source_code.html"><strong aria-hidden="true">3.10.</strong> SwiftUI source code</a></li><li class="chapter-item "><a href="../../posts/swift/use_swift_fetch_iciba_api.html"><strong aria-hidden="true">3.11.</strong> use swift fetch iciba API</a></li></ol></li><li class="chapter-item "><a href="../../posts/ios/ios.html"><strong aria-hidden="true">4.</strong> ios</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/ios/cocaposd_setup_and_install_for_ios_project.html"><strong aria-hidden="true">4.1.</strong> cocaposd setup and install for ios project</a></li><li class="chapter-item "><a href="../../posts/ios/swiftui_show_gif_image.html"><strong aria-hidden="true">4.2.</strong> SwiftUI show gif image</a></li><li class="chapter-item "><a href="../../posts/ios/implement_task_planner_app.html"><strong aria-hidden="true">4.3.</strong> implement Task planner App</a></li></ol></li><li class="chapter-item "><a href="../../posts/objective_c/objective_c.html"><strong aria-hidden="true">5.</strong> objective_c</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/objective_c/objective_c_cheat_sheet.html"><strong aria-hidden="true">5.1.</strong> Objective-C Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/objective_c/objective_c_for_absolute_beginners_read_note.html"><strong aria-hidden="true">5.2.</strong> Objective-C Note</a></li></ol></li><li class="chapter-item "><a href="../../posts/dart/dart.html"><strong aria-hidden="true">6.</strong> dart</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/dart/flutter.html"><strong aria-hidden="true">6.1.</strong> Flutter Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/dart/dart_cheat_sheet.html"><strong aria-hidden="true">6.2.</strong> Dart Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/flutter/flutter_dev_test.html"><strong aria-hidden="true">6.3.</strong> Flutter dev test</a></li></ol></li><li class="chapter-item "><a href="../../posts/rust/rust.html"><strong aria-hidden="true">7.</strong> rust</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/rust/offline_use_rust.html"><strong aria-hidden="true">7.1.</strong> Offline use rust</a></li><li class="chapter-item "><a href="../../posts/rust/rust_grammer.html"><strong aria-hidden="true">7.2.</strong> rust grammar</a></li><li class="chapter-item "><a href="../../posts/rust/pase_string_and_decimal_conversion.html"><strong aria-hidden="true">7.3.</strong> pase string and decimal conversion</a></li><li class="chapter-item "><a href="../../posts/rust/parse_types.html"><strong aria-hidden="true">7.4.</strong> rust types</a></li><li class="chapter-item "><a href="../../posts/rust/rust_life_cycle.html"><strong aria-hidden="true">7.5.</strong> Rust life cycle</a></li><li class="chapter-item "><a href="../../posts/rust/rust_generic.html"><strong aria-hidden="true">7.6.</strong> rust generics</a></li><li class="chapter-item "><a href="../../posts/rust/rust_implment_matrix.html"><strong aria-hidden="true">7.7.</strong> Rust implement matrix</a></li><li class="chapter-item "><a href="../../posts/rust/rust_sort.html"><strong aria-hidden="true">7.8.</strong> Rust implement sort algorithms</a></li><li class="chapter-item "><a href="../../posts/rust/implement_aes_encryption.html"><strong aria-hidden="true">7.9.</strong> Rust implement AEC encryption and decryption</a></li><li class="chapter-item "><a href="../../posts/rust/implement_trie_data_structure.html"><strong aria-hidden="true">7.10.</strong> implement trie data structure</a></li><li class="chapter-item "><a href="../../posts/rust/rust_implement_tree.html"><strong aria-hidden="true">7.11.</strong> implement tree data_structure</a></li><li class="chapter-item "><a href="../../posts/rust/list_dir.html"><strong aria-hidden="true">7.12.</strong> list dir</a></li><li class="chapter-item "><a href="../../posts/rust/fast_way_to_implment_object_trait.html"><strong aria-hidden="true">7.13.</strong> fast way to implment object trait</a></li><li class="chapter-item "><a href="../../posts/rust/compress_rust_binary_size.html"><strong aria-hidden="true">7.14.</strong> compress rust binary size</a></li><li class="chapter-item "><a href="../../posts/rust/implment_file_upload_backend.html"><strong aria-hidden="true">7.15.</strong> impliment file upload</a></li><li class="chapter-item "><a href="../../posts/rust/this_is_add_post_cli_implementation_in_rust.html"><strong aria-hidden="true">7.16.</strong> this is add_post cli implementation in rust</a></li><li class="chapter-item "><a href="../../posts/rust/use_rust_implment_a_copyclipbord_cli.html"><strong aria-hidden="true">7.17.</strong> Use rust implment a copyclipbord CLI</a></li><li class="chapter-item "><a href="../../posts/rust/sqlite_database_add_delete_update_show_in_rust.html"><strong aria-hidden="true">7.18.</strong> sqlite database add delete update show in rust</a></li><li class="chapter-item "><a href="../../posts/rust/implementing_tokio_joinhandle_for_wasm.html"><strong aria-hidden="true">7.19.</strong> Implementing tokio JoinHandle for wasm</a></li><li class="chapter-item "><a href="../../posts/rust/rust_implement_a_crate_for_encode_and_decode_brainfuck_and_ook.html"><strong aria-hidden="true">7.20.</strong> rust implement a crate for encode and decode brainfuck and ook</a></li><li class="chapter-item "><a href="../../posts/rust/slint_builtin_elements.html"><strong aria-hidden="true">7.21.</strong> Slint Builtin Elements</a></li><li class="chapter-item "><a href="../../posts/rust/corporate_network_install_rust_on_windows.html"><strong aria-hidden="true">7.22.</strong> Corporate network install Rust on windows</a></li><li class="chapter-item "><a href="../../posts/rust/rust_binary_file_how_to_judge_static_link_or_dynamic_link_in_macos.html"><strong aria-hidden="true">7.23.</strong> rust binary file how to judge static link or dynamic link in Macos</a></li><li class="chapter-item "><a href="../../posts/rust/rust_binary_include_dir_and_get_contents.html"><strong aria-hidden="true">7.24.</strong> rust binary include dir and get contents</a></li><li class="chapter-item "><a href="../../posts/rust/rust_logger_non-block.html"><strong aria-hidden="true">7.25.</strong> rust logger non-block</a></li><li class="chapter-item "><a href="../../posts/rust/rust_connect_sql_server_database.html"><strong aria-hidden="true">7.26.</strong> rust connect sql server database</a></li><li class="chapter-item "><a href="../../posts/rust/rust_websocket_implment.html"><strong aria-hidden="true">7.27.</strong> rust websocket implment</a></li></ol></li><li class="chapter-item "><a href="../../posts/java/java.html"><strong aria-hidden="true">8.</strong> java</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/java/java_grammar.html"><strong aria-hidden="true">8.1.</strong> java grammar and codewar</a></li><li class="chapter-item "><a href="../../posts/java/run_jar.html"><strong aria-hidden="true">8.2.</strong> java run .jar</a></li><li class="chapter-item "><a href="../../posts/java/java_pomxml_add_defaultgoal_to_build.html"><strong aria-hidden="true">8.3.</strong> Java pomxml add defaultGoal to build</a></li><li class="chapter-item "><a href="../../posts/java/java_set_mvn_mirror.html"><strong aria-hidden="true">8.4.</strong> Java set mvn mirror</a></li></ol></li><li class="chapter-item "><a href="../../posts/python/python.html"><strong aria-hidden="true">9.</strong> python</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/python/convert_pesn.html"><strong aria-hidden="true">9.1.</strong> convert pesn</a></li><li class="chapter-item "><a href="../../posts/python/find_remove_dir.html"><strong aria-hidden="true">9.2.</strong> find and remove dir</a></li><li class="chapter-item "><a href="../../posts/python/timing_message.html"><strong aria-hidden="true">9.3.</strong> wechat send message</a></li><li class="chapter-item "><a href="../../posts/python/use_python_openpyxl_package_read_and_edit_excel_files.html"><strong aria-hidden="true">9.4.</strong> Use python openpyxl package read and edit excel files</a></li></ol></li><li class="chapter-item "><a href="../../posts/go/go.html"><strong aria-hidden="true">10.</strong> go</a></li><li class="chapter-item "><a href="../../posts/js/js.html"><strong aria-hidden="true">11.</strong> js</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/js/js_tutorial.html"><strong aria-hidden="true">11.1.</strong> js tutorial</a></li><li class="chapter-item "><a href="../../posts/js/js_tutorial_map.html"><strong aria-hidden="true">11.2.</strong> ja map</a></li><li class="chapter-item "><a href="../../posts/js/js_tutorial_math.html"><strong aria-hidden="true">11.3.</strong> js math</a></li><li class="chapter-item "><a href="../../posts/js/js_tutorial_object.html"><strong aria-hidden="true">11.4.</strong> js object</a></li><li class="chapter-item "><a href="../../posts/js/js_tutorial_set.html"><strong aria-hidden="true">11.5.</strong> js set</a></li><li class="chapter-item "><a href="../../posts/js/single_thread_and_asynchronous.html"><strong aria-hidden="true">11.6.</strong> single thread and asynchronous</a></li><li class="chapter-item "><a href="../../posts/js/this.html"><strong aria-hidden="true">11.7.</strong> js this</a></li><li class="chapter-item "><a href="../../posts/js/js_implment_aes.html"><strong aria-hidden="true">11.8.</strong> js implment aes</a></li><li class="chapter-item "><a href="../../posts/js/getting_started_with_ajax.html"><strong aria-hidden="true">11.9.</strong> getting started with ajax</a></li><li class="chapter-item "><a href="../../posts/js/BinarySearchTree.html"><strong aria-hidden="true">11.10.</strong> binary search tree</a></li><li class="chapter-item "><a href="../../posts/js/goole_zx.html"><strong aria-hidden="true">11.11.</strong> goole zx</a></li><li class="chapter-item "><a href="../../posts/js/es6.html"><strong aria-hidden="true">11.12.</strong> es6</a></li></ol></li><li class="chapter-item expanded "><a href="../../posts/ruby/ruby.html"><strong aria-hidden="true">12.</strong> ruby</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/ruby/rails_setup_env.html"><strong aria-hidden="true">12.1.</strong> ruby on rails setup environment</a></li><li class="chapter-item expanded "><a href="../../posts/ruby/learn_ruby.html" class="active"><strong aria-hidden="true">12.2.</strong> learn ruby</a></li><li class="chapter-item "><a href="../../posts/ruby/ruby_note.html"><strong aria-hidden="true">12.3.</strong> Ruby Note</a></li><li class="chapter-item "><a href="../../posts/ruby/setup_ruby_for_ctf.html"><strong aria-hidden="true">12.4.</strong> Setup ruby for CTF</a></li></ol></li><li class="chapter-item "><a href="../../posts/react/react.html"><strong aria-hidden="true">13.</strong> react</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/react/react_life_cycle.html"><strong aria-hidden="true">13.1.</strong> react life cycle</a></li><li class="chapter-item "><a href="../../posts/react/react_router.html"><strong aria-hidden="true">13.2.</strong> react router</a></li><li class="chapter-item "><a href="../../posts/react/react_this.html"><strong aria-hidden="true">13.3.</strong> react this</a></li><li class="chapter-item "><a href="../../posts/react/react_interviw.html"><strong aria-hidden="true">13.4.</strong> react interview</a></li><li class="chapter-item "><a href="../../posts/react/important_react_interview.html"><strong aria-hidden="true">13.5.</strong> important react interview</a></li><li class="chapter-item "><a href="../../posts/react/react_quick_reference.html"><strong aria-hidden="true">13.6.</strong> react quick reference</a></li><li class="chapter-item "><a href="../../posts/react/redux_quick_reference.html"><strong aria-hidden="true">13.7.</strong> redux quick reference</a></li></ol></li><li class="chapter-item "><a href="../../posts/vue/vue.html"><strong aria-hidden="true">14.</strong> vue</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/vue/vue_ajax.html"><strong aria-hidden="true">14.1.</strong> vue ajax</a></li></ol></li><li class="chapter-item "><a href="../../posts/angular/angular.html"><strong aria-hidden="true">15.</strong> angular</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/angular/controller_communication.html"><strong aria-hidden="true">15.1.</strong> controller communication</a></li><li class="chapter-item "><a href="../../posts/angular/creating_custom_directives.html"><strong aria-hidden="true">15.2.</strong> creating custom directives</a></li><li class="chapter-item "><a href="../../posts/angular/directive_notes.html"><strong aria-hidden="true">15.3.</strong> directive notes</a></li><li class="chapter-item "><a href="../../posts/angular/directive_communication.html"><strong aria-hidden="true">15.4.</strong> directive communication</a></li><li class="chapter-item "><a href="../../posts/angular/post_params.html"><strong aria-hidden="true">15.5.</strong> post params</a></li><li class="chapter-item "><a href="../../posts/angular/read_json_angular.html"><strong aria-hidden="true">15.6.</strong> read json angular</a></li><li class="chapter-item "><a href="../../posts/angular/same_route_reload.html"><strong aria-hidden="true">15.7.</strong> same route reload</a></li></ol></li><li class="chapter-item "><a href="../../posts/css/css.html"><strong aria-hidden="true">16.</strong> css</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/css/use_css_media.html"><strong aria-hidden="true">16.1.</strong> use css media</a></li></ol></li><li class="chapter-item "><a href="../../posts/php/php.html"><strong aria-hidden="true">17.</strong> php</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/php/for_php_string_implment_some_extemtion_functions.html"><strong aria-hidden="true">17.1.</strong> for php string implment some extemtion functions</a></li><li class="chapter-item "><a href="../../posts/php/php_cheatsheet.html"><strong aria-hidden="true">17.2.</strong> PHP cheatsheet</a></li></ol></li><li class="chapter-item "><a href="../../posts/leetcode/leetcode.html"><strong aria-hidden="true">18.</strong> leetcode</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/leetcode/rust_leetcode.html"><strong aria-hidden="true">18.1.</strong> rust leetcode</a></li><li class="chapter-item "><a href="../../posts/leetcode/rust_codewar.html"><strong aria-hidden="true">18.2.</strong> rust codewar</a></li><li class="chapter-item "><a href="../../posts/leetcode/swift_codewar.html"><strong aria-hidden="true">18.3.</strong> swift codewar</a></li><li class="chapter-item "><a href="../../posts/leetcode/js_leetcode.html"><strong aria-hidden="true">18.4.</strong> js leetcode</a></li><li class="chapter-item "><a href="../../posts/leetcode/java_leetcode.html"><strong aria-hidden="true">18.5.</strong> java leetcode</a></li><li class="chapter-item "><a href="../../posts/leetcode/rust_huawei.html"><strong aria-hidden="true">18.6.</strong> huawei test</a></li><li class="chapter-item "><a href="../../posts/leetcode/rust_utils.html"><strong aria-hidden="true">18.7.</strong> rust common functions</a></li><li class="chapter-item "><a href="../../posts/leetcode/olympiad_training.html"><strong aria-hidden="true">18.8.</strong> Computer olympiad training</a></li></ol></li><li class="chapter-item "><a href="../../posts/ctf/CTF.html"><strong aria-hidden="true">19.</strong> ctf</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/ctf/CTF_Note.html"><strong aria-hidden="true">19.1.</strong> CTF Note</a></li><li class="chapter-item "><a href="../../posts/ctf/0.1_Web.html"><strong aria-hidden="true">19.2.</strong> Web</a></li><li class="chapter-item "><a href="../../posts/ctf/4.1_Misc.html"><strong aria-hidden="true">19.3.</strong> Misc</a></li><li class="chapter-item "><a href="../../posts/ctf/3.2_PWN_note.html"><strong aria-hidden="true">19.4.</strong> PWN</a></li><li class="chapter-item "><a href="../../posts/ctf/3.1_Crypto.html"><strong aria-hidden="true">19.5.</strong> Crypto</a></li><li class="chapter-item "><a href="../../posts/ctf/3.4_RSA_note.html"><strong aria-hidden="true">19.6.</strong> Rsa attack</a></li><li class="chapter-item "><a href="../../posts/ctf/3.5_Base64.html"><strong aria-hidden="true">19.7.</strong> Base64</a></li><li class="chapter-item "><a href="../../posts/ctf/0.0_SQL Injection Cheatsheet.html"><strong aria-hidden="true">19.8.</strong> SQL Injection Cheatsheet</a></li><li class="chapter-item "><a href="../../posts/ctf/1.1_SQL_injection.html"><strong aria-hidden="true">19.9.</strong> SQL Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.2_SQL_injection_UNION_attacks.html"><strong aria-hidden="true">19.10.</strong> SQL Injection UNION attacks</a></li><li class="chapter-item "><a href="../../posts/ctf/1.3_Blind SQL injection.html"><strong aria-hidden="true">19.11.</strong> Blind SQL Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.4_Code Injection.html"><strong aria-hidden="true">19.12.</strong> Code Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.5_SSRF.html"><strong aria-hidden="true">19.13.</strong> SSRF</a></li><li class="chapter-item "><a href="../../posts/ctf/1.6_OS command injection.html"><strong aria-hidden="true">19.14.</strong> OS command injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.7_Local file inclusion.html"><strong aria-hidden="true">19.15.</strong> Local file inclusion</a></li><li class="chapter-item "><a href="../../posts/ctf/1.8_Remote file inclusion.html"><strong aria-hidden="true">19.16.</strong> Remote file inclusion</a></li><li class="chapter-item "><a href="../../posts/ctf/1.9_CSRFm.html"><strong aria-hidden="true">19.17.</strong> CSRF</a></li><li class="chapter-item "><a href="../../posts/ctf/1.10_NoSQL injection.html"><strong aria-hidden="true">19.18.</strong> NoSQL injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.11_JSON injection.html"><strong aria-hidden="true">19.19.</strong> JSON injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.12_CTF_Web_SQL_Note.html"><strong aria-hidden="true">19.20.</strong> CTF Web SQL Note</a></li><li class="chapter-item "><a href="../../posts/ctf/2.1_XXE.html"><strong aria-hidden="true">19.21.</strong> XXE</a></li><li class="chapter-item "><a href="../../posts/ctf/2.2_XSS.html"><strong aria-hidden="true">19.22.</strong> XSS</a></li><li class="chapter-item "><a href="../../posts/ctf/2.3_Upload File.html"><strong aria-hidden="true">19.23.</strong> Upload File</a></li><li class="chapter-item "><a href="../../posts/ctf/2.4_serialize_unserialize.html"><strong aria-hidden="true">19.24.</strong> serialize unserialize</a></li><li class="chapter-item "><a href="../../posts/ctf/2.5_Race condition.html"><strong aria-hidden="true">19.25.</strong> Race condition</a></li><li class="chapter-item "><a href="../../posts/ctf/3.2_PWN_note.html"><strong aria-hidden="true">19.26.</strong> PWN_note</a></li><li class="chapter-item "><a href="../../posts/ctf/3.3_pwn HCTF2016 brop.html"><strong aria-hidden="true">19.27.</strong> pwn HCTF2016 brop</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_patch_defense_skill.html"><strong aria-hidden="true">19.28.</strong> PWN Patch defense skill</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_stack_overflow.html"><strong aria-hidden="true">19.29.</strong> PWN stack overflow</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_heap_overflow.html"><strong aria-hidden="true">19.30.</strong> PWN heap overflow</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_format_string_vulnerability.html"><strong aria-hidden="true">19.31.</strong> PWN Format String Vulnerability</a></li><li class="chapter-item "><a href="../../posts/ctf/kali_linux_tutorials.html"><strong aria-hidden="true">19.32.</strong> Kali linux tutorials</a></li><li class="chapter-item "><a href="../../posts/ctf/google_dorks_2023_lists.html"><strong aria-hidden="true">19.33.</strong> Google Dorks 2023 Lists</a></li><li class="chapter-item "><a href="../../posts/ctf/dvwa_writeup.html"><strong aria-hidden="true">19.34.</strong> DVWA WriteUp</a></li><li class="chapter-item "><a href="../../posts/ctf/bwapp_writeup.html"><strong aria-hidden="true">19.35.</strong> bWAPP WriteUp</a></li><li class="chapter-item "><a href="../../posts/ctf/sqlilabs_writeup.html"><strong aria-hidden="true">19.36.</strong> sqlilabs WriteUp</a></li><li class="chapter-item "><a href="../../posts/ctf/ctf_train_at_hangzhou.html"><strong aria-hidden="true">19.37.</strong> ctf train at hangzhou</a></li><li class="chapter-item "><a href="../../posts/ctf/ctf_common_mindmap_list.html"><strong aria-hidden="true">19.38.</strong> ctf common mindmap list</a></li><li class="chapter-item "><a href="../../posts/ctf/error_based_sql_injection.html"><strong aria-hidden="true">19.39.</strong> Error Based SQL Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/urlfinder_tutorial.html"><strong aria-hidden="true">19.40.</strong> URLFinder Tutorial</a></li><li class="chapter-item "><a href="../../posts/ctf/observer_ward_tutorial.html"><strong aria-hidden="true">19.41.</strong> observer_ward Tutorial</a></li><li class="chapter-item "><a href="../../posts/ctf/mysql_udf_.html"><strong aria-hidden="true">19.42.</strong> MySQL UDF 提权</a></li><li class="chapter-item "><a href="../../posts/ctf/nuclei__tutorial.html"><strong aria-hidden="true">19.43.</strong> Nuclei Tutorial</a></li><li class="chapter-item "><a href="../../posts/ctf/2024_ctf_solution_thinking.html"><strong aria-hidden="true">19.44.</strong> 2024 ctf solution thinking</a></li><li class="chapter-item "><a href="../../posts/ctf/man_che_si_te_bian_ma.html"><strong aria-hidden="true">19.45.</strong> 曼彻斯特编码</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Andrew&#x27;s Blog</h1>
<div class="right-buttons">
<a href="https://gitlink.org.cn/dnrops/dnrops.gitlink.net.git" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="learn-ruby"><a class="header" href="#learn-ruby">learn ruby</a></h1>
<h2 id="print"><a class="header" href="#print">print</a></h2>
<pre><code class="language-ruby">#in ruby print can be use print or puts
print "#in ruby print can be use print or puts"
puts "#in ruby print can be use print or puts"
p "#in ruby print can be use print or puts"
#these three methods all the same
#but p will auto add newline
</code></pre>
<h2 id="number"><a class="header" href="#number">number</a></h2>
<pre><code class="language-ruby">n_0 = 150
#multiple
n_1 = n_0*9
#divide
n_2 = n_0/15
#subtract
n_3 = n_0-n_2
#addition
n_4 = n_0+n_2
#power
n_5 = n_4**3
#sqrt
n_6 = Math.sqrt(n_5)
#slice
n_7 = 15[0..]
#向上取整
25.round(-1, half: :up) # =&gt; 30
(-25).round(-1, half: :up) # =&gt; -30
# 向下取整
25.round(-1, half: :down) # =&gt; 20
(-25).round(-1, half: :down) # =&gt; -20
#Round up 向上取整
n_8 = 1.25.ceil(0)
#Round floor
n_9 = 1.66514.floor() # 向下取整
# n_9 = 1.66514.floor(1) # 保留一位数
# n_9 = 1.66514.floor(2) # 保留两位数
#integer to character and char to integer
p 122.chr #“z”
p 'a'.ord #97
p "n_1 = #{n_1}"
p "n_2 = #{n_2}"
p "n_3 = #{n_3}"
p "n_4 = #{n_4}"
p "n_5 = #{n_5}"
p "n_6 = #{n_6}"
p "n_7 = #{n_7}"
p "n_8 = #{n_8}"
p "n_9 = #{n_9}"
12345.digits # =&gt; [5, 4, 3, 2, 1]
p 55.digits(2) # 转换为二进制 [1, 1, 1, 0, 1, 1]
p 50.divmod(3) #余数 array
# Returns the greatest common divisor of the two integers. The result is always positive. 0.gcd(x) and x.gcd(0) return x.abs.
36.gcd(60) #=&gt; 12
2.gcd(2) #=&gt; 2
3.gcd(-7) #=&gt; 1
# Returns an array with the greatest common divisor and the least common multiple of the two integers, [gcd, lcm].
36.gcdlcm(60) #=&gt; [12, 180]
2.gcdlcm(2) #=&gt; [2, 2]
3.gcdlcm(-7) #=&gt; [1, 21]
# Returns the least common multiple of the two integers.
36.lcm(60) #=&gt; 180
2.lcm(2) #=&gt; 2
3.lcm(-7) #=&gt; 21
#余数
11.remainder(4) # =&gt; 3
#int to float
1.to_f # =&gt; 1.0
#float to int
p 1.5.to_i # =&gt; 1
#进制转换
12345.to_s # =&gt; "12345"
12345.to_s(2) # =&gt; "11000000111001"
12345.to_s(8) # =&gt; "30071"
12345.to_s(10) # =&gt; "12345"
12345.to_s(16) # =&gt; "3039"
12345.to_s(36) # =&gt; "9ix"
78546939656932.to_s(36) # =&gt; "rubyrules"
sprintf("%X", ~0x1122334455) #=&gt; "..FEEDDCCBBAA"
</code></pre>
<h2 id="random-number"><a class="header" href="#random-number">random number</a></h2>
<pre><code class="language-ruby">p rand
def rand_by_range(min, max)
return (rand * (max - min + 1)).floor + min;
end
p rand_by_range(15,20) #generates random integer at range (&gt;=15 and &lt;=20)
p self.rand_by_range(1,20)
p self # main
</code></pre>
<h2 id="string"><a class="header" href="#string">string</a></h2>
<pre><code class="language-ruby">#new string
s_00 = String.new
p s_00 # ""
p s_00.encoding # #&lt;Encoding:ASCII-8BIT&gt;
#set encoding
s_01 = String.new("string",encoding: 'ASCII')
p s_01
#set encoding and capacity
s_02 = String.new('hello', encoding: 'UTF-8', capacity: 25)
p s_02
# string % object → new_string
#number prepend with spaces if length is not 10
s_03 = "%#10d" % 123
s_03 = "%010d" % 123 #prepend with 0
s_03 = "% 10d" % 123 #prepend with spaces
p s_03
#string * integer → new_string
s_04 ="this "*4
p s_04 # "this this this this "
# difine some string
name = "Andrew Ryan"
print "#{name}\n"
# as_bytes
s_0 = "hello"
s_0_arr = s_0.bytes
print "string to bytes:#{s_0_arr}\n"
#concat two string
s_1 = "s1"
s_2 = "s2"
s_3 = s_1+s_2
print "#{s_3}\n"
#concat string and number or number to string
n_0 = 153
ns = "#{s_1}#{n_0}"
print "string and num:#{ns}\n"
#length of string
s_4 = "this is a string"
s_4_len = s_4.length
print s_4_len
#include or contains in ruby string
s_5 = "this is a string"
s_5_h = s_5.include? "a"
p s_5_h
# string to uppercase
p "my string".yield_self {|s| s.upcase } #=&gt; "MY STRING"
#parse string to integer
s_6 = "100"
p s_6.to_i
#parse string to floating point
p s_6.to_f
</code></pre>
<h2 id="array"><a class="header" href="#array">array</a></h2>
<pre><code class="language-ruby">#for earch
['toast', 'cheese', 'wine'].each { |food| p "#{food.capitalize}" }
# enumerate
['toast', 'cheese', 'wine'].each_with_index do |food, index| p "#{index}:#{food}"end
arr = Array.new #=&gt; []
5.times {|i| arr.push(i) }
p arr
arr1 = []
5.upto(10) {|i| arr1&lt;&lt; i } #5..=10
p arr1
Array.new(4) {Hash.new} #=&gt; [{}, {}, {}, {}]
Array.new(4) {|i| i.to_s } #=&gt; ["0", "1", "2", "3"]
empty_table = Array.new(3) {Array.new(3)}
#=&gt; [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
Array({:a =&gt; "a", :b =&gt; "b"}) #=&gt; [[:a, "a"], [:b, "b"]]
arr = [1, 2, 3, 4, 5, 6]
arr[2] #=&gt; 3
arr[100] #=&gt; nil
arr[-3] #=&gt; 4
arr[2, 3] #=&gt; [3, 4, 5]
arr[1..4] #=&gt; [2, 3, 4, 5]
arr[1..-3] #=&gt; [2, 3, 4]
arr.at(0) #=&gt; 1
arr.first #=&gt; 1
arr.last #=&gt; 6
arr.take(3) #=&gt; [1, 2, 3]
arr.drop(3) #=&gt; [4, 5, 6]
browsers = ['Chrome', 'Firefox', 'Safari', 'Opera', 'IE']
browsers.length #=&gt; 5
browsers.count #=&gt; 5
browsers.include?('Konqueror') #=&gt; false
arr = [1, 2, 3, 4]
arr.push(5) #=&gt; [1, 2, 3, 4, 5]
arr &lt;&lt; 6 #=&gt; [1, 2, 3, 4, 5, 6]
#push front
arr.unshift(0) #=&gt; [0, 1, 2, 3, 4, 5, 6]
arr.insert(3, 'orange', 'pear', 'grapefruit')
#=&gt; [0, 1, 2, "orange", "pear", "grapefruit", "apple", 3, 4, 5, 6]
arr = [1, 2, 3, 4, 5, 6]
arr.pop #=&gt; 6
arr.shift #=&gt; 1
arr.delete_at(2) #=&gt; 4
arr.delete(2) #=&gt; delete all 2
# remove nil values
arr = ['foo', 0, nil, 'bar', 7, 'baz', nil]
arr.compact #=&gt; ['foo', 0, 'bar', 7, 'baz']
# non-destructive uniq dedup
arr = [2, 5, 6, 556, 6, 6, 8, 9, 0, 123, 556]
arr.uniq #=&gt; [2, 5, 6, 556, 8, 9, 0, 123]
arr = [1, 2, 3, 4, 5]
arr.each {|a| print a -= 10, " "}
# prints: -9 -8 -7 -6 -5
p ""
#reverse to string
words = %w[first second third fourth fifth sixth] #["first", "second", "third", "fourth", "fifth", "sixth"]
p words
str = ""
words.reverse_each {|word| str += "#{word} "}
p str #=&gt; "sixth fifth fourth third second first "
#reverser
a = ['foo', 'bar', 'two']
a1 = a.reverse
arr.map {|a| 2*a} #=&gt; [2, 4, 6, 8, 10]
p arr #=&gt; [1, 2, 3, 4, 5]
arr = [1, 2, 3, 4, 5, 6]
arr.select {|a| a &gt; 3} #=&gt; [4, 5, 6]
arr.reject {|a| a &lt; 3} #=&gt; [3, 4, 5, 6]
arr.drop_while {|a| a &lt; 4} #=&gt; [4, 5, 6]
arr.delete_if {|a| a &lt; 4} #=&gt; [4, 5, 6]
arr.keep_if {|a| a &lt; 4} #=&gt; [1, 2, 3]
a = 'abcde'.split('').shuffle
a # =&gt; ["e", "b", "d", "a", "c"]
a1 = a.sort
a1 # =&gt; ["a", "b", "c", "d", "e"]
</code></pre>
<h2 id="function"><a class="header" href="#function">function</a></h2>
<pre><code class="language-ruby">def one_plus_one
1 + 1
end
p one_plus_one
def say_goodnight(name)
"Good night, #{name.capitalize}"
end
p say_goodnight("Andrew")
</code></pre>
<h2 id="class"><a class="header" href="#class">class</a></h2>
<pre><code class="language-ruby">class Person
def initialize(*args)
@name = args[0]
@age = args[1]
end
def name
@name
end
def age
@age
end
end
pp1 = Person.new("Andrew",26)
p pp1
p pp1.name
p pp1.age
person = Class.new do
def initialize(*args)
@name = args[0]
@age = args[1]
end
def name
@name
end
def age
@age
end
def run
p self
p self.name
p self.age
end
end
pp2 = person.new("Ryan",25)
p pp2.run
</code></pre>
<h2 id="struct"><a class="header" href="#struct">struct</a></h2>
<pre><code class="language-ruby">Person = Struct.new(:name, :age)
me = Person["Andrew",26]
p me
p me.name
</code></pre>
<h2 id="loop"><a class="header" href="#loop">loop</a></h2>
<pre><code class="language-ruby">5.times { print "Odelay!" }
=begin
#forever loop
loop do
print "Much better."
print "Ah. More space!"
print "My back was killin' me in those crab pincers."
end
=end
</code></pre>
<h2 id="json"><a class="header" href="#json">json</a></h2>
<pre><code class="language-ruby">require 'json'
json = JSON.parse("{\"name\"=\"ansrew\"}")
p json
</code></pre>
<h2 id="file-system"><a class="header" href="#file-system">file system</a></h2>
<pre><code class="language-ruby">#read all lines
File.open("./file/demo.txt") do |f|
# f_string = f.gets #read first line
f_string = f.read
p f_string
end
#read to string array split by "\n"
File.open("./file/demo.txt") do |f|
f_arr = f.read.split("\n")
p f_arr
end
#read each line
File.foreach("./file/demo.txt") { |line| puts line }
#write to file
File.open("./file/log.txt", "w") { |f| f.write "#{Time.now} - User logged in\n" }
# ||
File.write("./file/log.txt","some data")
#append to log file
File.write("./file/log.txt", [1,2,3].join("\n"), mode: "a")
# Renaming a file
File.rename("./file/log.txt", "./file/new_log.txt")
# File size in bytes
File.size("./file/new_log.txt")
# Does this file already exist?
File.exists?("./file/new_log.txt")
# Get the file extension, this works even if the file doesn't exists
File.extname("./file/new_log.txt")
# =&gt; ".txt"
# Get the file name without the directory part
File.basename("./file/new_log.txt")
# =&gt; "new_log.txt"
# Get the path for this file, without the file name
File.dirname("./file/new_log.txt")
# =&gt; "./"
# Is this actually a file or a directory?
File.directory?("./")
#list current dir
def find_files_in_current_directory
entries = Dir.entries("./")
entries.reject { |entry| File.directory?(entry) }
end
dir_list = find_files_in_current_directory()
# p dir_list
#get the status of dir or file
File.stat("/home")
File.stat("./file/demo.txt")
# All files in current directory
dir_list = Dir.glob("*")
p dir_list
# All files containing "spec" in the name
Dir.glob("*spec*")
# All ruby files
Dir.glob("*.rb")
#get current working directory
Dir.pwd #"/home/andrew/code/jihulab/ruby_code/learn_ruby"
#is empty
Dir.empty?("/tmp")
#make dir
10.times do |i| #0..=9
Dir.mkdir("/tmp/test#{i}")
end
#is exists
Dir.exists?("/home/jesus")
</code></pre>
<h2 id="http-get"><a class="header" href="#http-get">http get</a></h2>
<pre><code class="language-ruby">require 'net/http'
Net::HTTP.start( 'blog.udemy.com', 80 ) do |http|
print( http.get( '/ruby-print/' ).body )
end
</code></pre>
<h2 id="run-cmd"><a class="header" href="#run-cmd">run cmd</a></h2>
<pre><code class="language-ruby">system("ls")
exec("du")
cmd = open("|date")
print cmd.gets
cmd.close
</code></pre>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../../posts/ruby/rails_setup_env.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../../posts/ruby/ruby_note.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../../posts/ruby/rails_setup_env.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../../posts/ruby/ruby_note.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<script src="../../ace.js"></script>
<script src="../../editor.js"></script>
<script src="../../mode-rust.js"></script>
<script src="../../theme-dawn.js"></script>
<script src="../../theme-tomorrow_night.js"></script>
<script src="../../elasticlunr.min.js"></script>
<script src="../../mark.min.js"></script>
<script src="../../searcher.js"></script>
<script src="../../clipboard.min.js"></script>
<script src="../../highlight.js"></script>
<script src="../../book.js"></script>
<!-- Custom JS scripts -->
<script src="../../src/js/custom.js"></script>
</div>
</body>
</html>