{"id":16807367,"url":"https://github.com/marclave/koans","last_synced_at":"2025-03-17T08:41:06.370Z","repository":{"id":81123833,"uuid":"89966085","full_name":"marclave/koans","owner":"marclave","description":"Getting started with Ruby 🚀","archived":false,"fork":false,"pushed_at":"2017-05-04T17:28:16.000Z","size":76,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-16T01:40:08.553Z","etag":null,"topics":["ruby","tutorial"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marclave.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-01T21:50:17.000Z","updated_at":"2017-05-04T19:56:17.000Z","dependencies_parsed_at":null,"dependency_job_id":"fc837ea8-6f59-42a4-a00c-7854852bdce9","html_url":"https://github.com/marclave/koans","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marclave%2Fkoans","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marclave%2Fkoans/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marclave%2Fkoans/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marclave%2Fkoans/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marclave","download_url":"https://codeload.github.com/marclave/koans/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244003131,"owners_count":20382130,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ruby","tutorial"],"created_at":"2024-10-13T09:53:38.715Z","updated_at":"2025-03-17T08:41:06.335Z","avatar_url":"https://github.com/marclave.png","language":"Ruby","readme":"# koans\nGetting started with Ruby\n\n\n## Key points \n\n### Assertions\n\nassert takes one or more arguments: boolean toAssert, string message\n\ncomparision can be done as input as follows\n```\none = 1\ntwo = 2\n\nassert one == two\n```\n\nEven more cool, there is an `assert_equal`\n```\nhouseGuests = 10\nhousePlates = 4\nassert_equal houseGuests, housePlates\n```\n\n### nil\n\nFirstly, you can either fo `kind_of?` or `is_a?` which both return true || false depending on if the class is of obj or if class is a superclass of obj. Or if its included in obj\n\n### Objects\n\nEverything appears to be an object so far, including nil\n\n`nil.to_s` and `nil.inspect` both return an empty string\n\nNo two objects has the same `id`\n\nIt appears the small integers ID patterns is as follows:\n```\n2*integer_value + 1\n\n```\n\n### Arrays (About)\n\nSame as every other language so far for arrays..\n\nOh this is neat, appending to an array can be done like\n\n```\narrayName \u003c\u003c 333\n\n```\n\nCan do `array.first` and can also do `array.last`. Also similar to python can index by negative like so `arr[-1]`\n\n`array[0..2]` Will take the zero index to second index `inclusive`\n\nWhere as `array[0...2]` Will take the zero index to second index `exclusive`\n\n\n### Arrays (Assignments)\n\nSimilar to golang, a non parrallel assignment is as follows\n```\nfriends = [\"John\", \"Smith\"]\n```\n\nSomething new, can do parallel assignments\n\n```\n  first_name, last_name = [\"John\", \"Smith\"]\n  assert_equal \"John\", first_name\n  assert_equal \"Smith\", last_name\n```\n\n`splat` is very cool, right now i would define it as breaking up an array without actually needing to loop over it.\n\n`double splat` is even cooler\n```\ndef go(x:, y:)\nend\n\npoint = { x: 100, y: 200 }\ngo(**point)\n``` \n\n### Hashes\n\nSimilar to golang except using the `=\u003e` symbol\n\nthe `#[]` will return the value if it exists, else `nil`. If we use the `#fetch` there are different options we can use.\n\nTaken from http://ruby-doc.org/core-1.9.3/Hash.html#method-i-fetch\n\nFor example if we wrap with an assert raise for KeyError.\n\n```\nassert_raise(KeyError) do\n  hash.fetch(:doesnt_exist)\nend\n```\n\nFor the bonus question it appeared I could not just use the literal, I am guessing for how the assert_equal handles the input?\n\nIf hashes are unordered, we can still do a compare and see if the two sets are equal\n\na hashes keys class are `Array`, same with a hashes values class\n\nMerging two hashes will take the hash being merged into old hash and if there are duplicates it will over write the old ones\n\nWhen instantiating a new `Hash` you can specify a default value in `h = Hash.new(\"default\")`\n\nThe `test_default_value_is_the_same_object` caught me off guard, but makes sense\n\n\n### Strings\n\nSingle and double quotes can be used for strings, need to check Stembolt coding guidelines\n\nIf nesting `\"\"` inside a string, use `''` to wrap, no need for escape characters\n\nFlexible quoting is my favourite, similar to `\"{0} first thing, {1} second\".format(1, 2)` in python\n\n```\na = %(flexible quotes can handle both ' and \" characters)\n```\n\n\nCan do concatenation with `+` operator.\n\nBonus question, first glance it feels more clean, however my guess is it doesnt need to create a new string every time. It is modifying the original.\n\nSingle quotes do not interpret escape chars, double quotes do.\n\nOnly double strings interpolate\n\njoin and split for strings and arrays are just that like python\n\n\n### Symbols\n\nThe reason they converted the symbols to strings was to compare the function, otherwise we couldn't.\n\n\nSymbols are immutable.\n\n### Regular Expressions\n\n\nIf you want to see if a pattern is in a string, can do the following\n\n```\nassert_equal \"match\", \"some matching content\"[/match/]\n\n```\n\nIf it doesnt match it returns a `nil`\n\nSo if `*` can match an empty string... It appears that it would be never? Tested on whitespace and trailing characters\n\n`*` is greedy because, depending on the tokenizing, I am sure it performs a lot of backtracking and incase the input data has not been messaged or handled properly, we could match up on a lot of information.\n\n\n`select` is an enumerator, so if you want to use it on an array for example\n\n```\nnumbers = [1, 2, 3, 4]\nevenNumbers = numbers.select { |number| number.even? }\n```\n\nI Enjoy the enumerator.\n\nNormal regular expression identifiers\n\nCapitalization of a shortcut negates it, can also use `^`\n\n`\"\\A\"` is start of the string, where as `\"\\z\"` is the end of the string\n\n\nCaret anchors tho the start of lines\n\nDollar sign anchors to end of lines\n\nScan is similar to findall\n\n### Methods\n\n\nAble to call a function without parenthesis, feeling uneasy want to see if this a best practice\n\n\nFunction names are made into symbols as soon as they are created\n\n### Keyword Arguments\n\nAlongside using default values, you can use keyword arguments. the main difference from appearance is when you call the function and you want to override the keyword value you must explicitly do so, instead of implicitly like default values\n\n\nIf you do not specify a value with a keyword argument that means it is required\n\n```\ndef foo(a, b: 'letterB')\n  [a, b]\nend\n\n```\n\n\n### Constants\n\nIs it best practice to have a class of constants, then ref them from other files? Or just have a constants file. I do this in c a lot so need to check.\n\n\ntop level constants are ref'd by `::` where as full path `ClassName::constant` is for the class constant\n\n\nlexicol scope has precidence over inheritance\n\n\nFor the last question there is no context for `LEGS` in the lexical scope so inheritance takes the cake\n\n\n### Control statements\n\nEvery statement returns a value, so this means we can use if statements in this way\n\n\nNew keyword `unless \u003ccondition\u003e` evaluates to `if !\u003ccondition\u003e`\n\n`next` statements are cool, they only run the next line if a condition is true. Looks to remove the indentation of a single if statement\n\nThere is the `.times` which if you do `10.times do ... end` it will do that block ten times\n\n\n### About true and false\n\n`nil` is treated as false, where everything except false is treated as true: \n```\n1\n0\n[]\n{}\n...\n```\n### Triangle Project\n\nSee `about_triangle_project.rb`\n\n\n### Exceptions\n\n`rescue` allows us to handle certain exceptions\n\nif you `fail` and provide a message, that is the exception message if you `rescue` it properly.\nthe flow is\n```\nbegin\n...\nrescue\n...\nensure [optional]\n```\n\nCan also raise and rescue new exceptions\n\n\n### Triangle Project 2\n\nSee `triangle.rb`\n\n\n### Iteration\n\nBlocks are cool for iterations, but also I feel as though less readable unless you have had ruby experience\n\nBreaks can be before `if` statement instead of nested inside if one liner\n\nCollect appears to be similar to the `map` from python\n\nOh haha it totally is\n\n\nfindall and select are, at the highest level, interchangeable\n\n`.find` finds the first occurence, based on a condition, in an array\n\n\n`inject` amalgamates all elements of iterator, can use a block to perform an operation.\n\nRuby way of summing an array `my_array.inject(0, :+)`\n\nBonus question\n\nMy first thought is that if it failed to open it will return `nil` to file\nso then in the `assert_equal` it will fail\nWhere as if you just tried to do `File.open` you would have to do a begin..rescue\n\nOn discussion, it closes the file automatically where as you have to manually close it with returning it\n\n### Blocks\n\n`block_given` will be useful\n\nblocks can change variables in outer scope\n\n\nExplained lambdas in ruby for me http://culttt.com/2015/05/13/what-are-lambdas-in-ruby/\n\n\n### Sandwhich\n\nSee `about_sandwhich_code.rb`\n\n### Scoring project\n\nSee `about_scoring_project.rb`\n\n\n### Classes\n\nSimilar to python\n\n\nformal accessor for instance variables\n\n```\nfido.instance_variable_get(\"@name\")\n```\n\nBecause initialize gets run on every instantiation, thus needing the proper arguments if required.\n\n### Open Classes\n\n\nI am curious as to what the advantage is to opening a class vs interfaces\n\n### Dice Project\n\nSee `about_dice_project.rb`\n\n### Inheritance \n\n\nSame as any other OOP Lang i've done so far\n\n\n### Modules\n\nModules are a way of providing methods you can use across lots of classes.\n\n\n### Scope\n\nPretty straight forward, you can infact get do some cool things like `const_get` and `constants`\n\n### Class methods\n\nI prefer the former over the latter, at least from a readability standpoint\n\n\n### Message\n\nEverytime you call a method of a class, its the same as sending a message with the method name symbol :)\n\nMy guess is that you can't re open __send__ but you can for send.\n\n\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarclave%2Fkoans","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarclave%2Fkoans","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarclave%2Fkoans/lists"}