# How to read Crystal documentation?

**URL:** <https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863>\
**Category:** Offtopic\
**Created:** [June 20, 2019, 5:48pm UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863 "2019-06-20T17:48:12Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![curious2learn](https://avatars.discourse-cdn.com/v4/letter/c/5daacb/32.png) [@curious2learn](https://forum.crystal-lang.org/u/curious2learn)\
**Post date:** [June 20, 2019, 5:48pm UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/1 "2019-06-20T17:48:12Z")

</div>

Today, I wanted to generate a `SHA256` hash of a string. Based on the documentation [here](https://crystal-lang.org/api/0.29.0/OpenSSL/Digest.html) and the stackoverflow post [here](https://stackoverflow.com/questions/42299037/crystal-how-can-i-find-the-sha256-hash-of-a-binary-value) I figured out the following working code:

```
require "openssl"

enc = OpenSSL::Digest.new("sha256")
res = enc.update("helloworld")
puts res

```

However, where does it say in the documentation that the name of the algorithm for this purpose should be “sha256”? How can I find the acceptable arguments to `OpenSSL::Digest.new()`.

Another one was when setting permissions for creating directories. I tried and failed to generate correct permissions using:

```
Dir.mkdir_p(destdir, mode = 774)

```

[Here](https://crystal-lang.org/api/0.29.0/Dir.html#mkdir_p%28path%2Cmode%3D511%29-class-method) it says that Dir.mkdir\_p(destdir, mode = 511) creates a new directory at the given path, including any non-existing intermediate directories. The linux-style permission mode can be specified, with a default of 777 (0o777). I believe this needs to be fixed (that is, the default is 511). But why does it not say that the mode has to specified in the `octal` format. When I tried 0o774, things worked.

In general, what is the recommended way of finding set of possible arguments and/or their type.

Thank you. BTW Crystal and Kemal combination is really awesome. I hope this language really takes off.

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [June 20, 2019, 6:06pm UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/2 "2019-06-20T18:06:38Z")

</div>

What you are finding is just lack of documentation. Many things were added to the standard library without proper documentation. We are always thankful if people send PRs with more documentation on things that are missing.

As for `mode = 511`, that’s a bug in the doc generator: the actual value is `0o777` but the doc generator, for some reason, converts that to it’s base 10 value, which is 511. There’s no need for the value to be octal, but it’s usual to write it in octal.

---

<div class="post-metadata">

**Author:** ![curious2learn](https://avatars.discourse-cdn.com/v4/letter/c/5daacb/32.png) [@curious2learn](https://forum.crystal-lang.org/u/curious2learn)\
**Post date:** [June 21, 2019, 10:20am UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/3 "2019-06-21T10:20:27Z")

</div>

Thank you @asterite. Unfortunately, I only work on either personal projects, or projects of 2-3 people. So not too familiar with how PRs work in a big project like Crystal. But would love to contribute to the documentation when I come across things such as these that can be clarified or improved upon. Are there any quick guides on how the PRs work for a such large projects?

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [June 21, 2019, 12:00pm UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/4 "2019-06-21T12:00:06Z")

</div>

[https://github.com/crystal-lang/crystal/blob/master/CONTRIBUTING.md](https://github.com/crystal-lang/crystal/blob/master/CONTRIBUTING.md) Would be a good place to start.

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [June 21, 2019, 12:39pm UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/5 "2019-06-21T12:39:37Z")

</div>

The instructions above are good, but if it’s just API documentation then it’s just like sending a PR to a project of any size. Be sure to run `crystal tool format` on the files you change (though this can be done later).

---

<div class="post-metadata">

**Author:** ![curious2learn](https://avatars.discourse-cdn.com/v4/letter/c/5daacb/32.png) [@curious2learn](https://forum.crystal-lang.org/u/curious2learn)\
**Post date:** [June 21, 2019, 1:25pm UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/6 "2019-06-21T13:25:56Z")

</div>

Thanks @Blacksmoke16 and @asterite. Will look into this.

---

<div class="post-metadata">

**Author:** ![girng](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/girng/32/127_2.png) [@girng](https://forum.crystal-lang.org/u/girng)\
**Post date:** [June 22, 2019, 7:29am UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/7 "2019-06-22T07:29:35Z")

</div>

This is the perfect opportunity @curious2learn to submit a PR for the docs. So the next person who stumbles upon that doc page will see the code and save time. Most importantly, you get to contribute to something special!

---

<div class="post-metadata">

**Author:** ![curious2learn](https://avatars.discourse-cdn.com/v4/letter/c/5daacb/32.png) [@curious2learn](https://forum.crystal-lang.org/u/curious2learn)\
**Post date:** [June 22, 2019, 6:23pm UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/8 "2019-06-22T18:23:22Z")

</div>

Okay. So I cloned the Crystal repository, created a new branch and added the above simple example in the file `openssl/digest/digest.cr`. This is the code I added.

````
# # Generate SHA256 hash of a string
# 
# ```
# enc = OpenSSL::Digest.new("sha256")
# enc.update("helloworld") # => 1a16eef5663e63cf4e88692c9c24dba001c5693e2ae92e944215d041456440b8
# ```

````

I find such small examples in the API docs very helpful. Before I create a pull request, I want to see how this looks in the generated documentation (to make sure that I have not screwed it up). How do I generate docs locally to check this out?

Regarding the file permissions, I suppose there is no way to correct that because of the error in the doc generator that @asterite has pointed out.

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [June 22, 2019, 6:35pm UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/9 "2019-06-22T18:35:22Z")

</div>

I’d also include the `require "openssl"`, having copy pastable examples is 💯.

Should just be able to run `make docs`.

---

<div class="post-metadata">

**Author:** ![curious2learn](https://avatars.discourse-cdn.com/v4/letter/c/5daacb/32.png) [@curious2learn](https://forum.crystal-lang.org/u/curious2learn)\
**Post date:** [June 22, 2019, 6:47pm UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/10 "2019-06-22T18:47:20Z")

</div>

Definitely. Will include that line.

I typed `make docs` in the root crystal folder, but got the following error:

```
Makefile:62: *** Could not locate llvm-config, make sure it is installed and in your PATH, or set LLVM_CONFIG. Stop.

```

[Here](https://groups.google.com/forum/#!topic/crystal-lang/8FXVLrl1RYs) I found the suggestion that I should run `brew link llvm --force`. Is that correct?

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [June 22, 2019, 7:01pm UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/11 "2019-06-22T19:01:09Z")

</div>

Not sure, can give it a try I guess?

---

<div class="post-metadata">

**Author:** ![curious2learn](https://avatars.discourse-cdn.com/v4/letter/c/5daacb/32.png) [@curious2learn](https://forum.crystal-lang.org/u/curious2learn)\
**Post date:** [June 22, 2019, 7:47pm UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/12 "2019-06-22T19:47:55Z")

</div>

I installed LLVM and then ran `make docs` as suggested by @Blacksmoke16.  
I got the following response:

```
Using /usr/local/opt/llvm/bin/llvm-config [version=8.0.0]
./bin/crystal docs -b https://crystal-lang.org/api/latest src/docs_main.cr

```

Then I opened `crystal/docs/OpenSSL/Digest.html`, but it does not reflect the changes I made. Can anyone help me with how I can see these changes?

Thanks.

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [June 22, 2019, 7:58pm UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/13 "2019-06-22T19:58:18Z")

</div>

Where exactly did you add the comment block in the file?

---

<div class="post-metadata">

**Author:** ![curious2learn](https://avatars.discourse-cdn.com/v4/letter/c/5daacb/32.png) [@curious2learn](https://forum.crystal-lang.org/u/curious2learn)\
**Post date:** [June 22, 2019, 11:30pm UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/14 "2019-06-22T23:30:26Z")

</div>

The following. I am going to add the line you suggested. But this is what I have in the  
`src/openssl/digest/digest.cr`. I added these lines _after_ the `require` lines but _before_ the `module OpenSSL`. Do I need to add these after the `module` declaration?

Edit: I tried adding after the `module` declaration, but that did not help either.

````
# # Generate SHA256 hash of a string
# 
# ```
# enc = OpenSSL::Digest.new("sha256")
# enc.update("helloworld") # => 1a16eef5663e63cf4e88692c9c24dba001c5693e2ae92e944215d041456440b8
# ```
````

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [June 22, 2019, 11:45pm UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/15 "2019-06-22T23:45:41Z")

</div>

You’re adding the docs to the `OpenSSL` _module_. So it would show up `/crystal/docs/OpenSSL.html`. You probably want to add it to the `update` method within the `Digest` class. Like:

````auto
    # Generate SHA256 hash of *data*.
    #
    # ```
    # require "openssl"
    #
    # OpenSSL::Digest.new("sha256").update("helloworld") # => 1a16eef5663e63cf4e88692c9c24dba001c5693e2ae92e944215d041456440b8
    # ```
    def update(data : String | Slice)

````

Also, @asterite do you know if there is any reason this class takes a string and not an `OpenSSL::Algorithm`? Would make more sense as you wouldn’t have to validate the string like it’s currently doing since all the valid ones would be in the enum?

---

<div class="post-metadata">

**Author:** ![curious2learn](https://avatars.discourse-cdn.com/v4/letter/c/5daacb/32.png) [@curious2learn](https://forum.crystal-lang.org/u/curious2learn)\
**Post date:** [June 23, 2019, 12:08am UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/16 "2019-06-23T00:08:40Z")

</div>

@Blacksmoke16 , sorry but it does not show up in `/crystal/docs/OpenSSL.html` either :(

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [June 23, 2019, 12:24am UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/17 "2019-06-23T00:24:13Z")

</div>

Just to be clear, by `crystal/docs/OpenSSL.html`, im talking about the `docs` directory in your `crystal` folder. I.e. where you run `make docs` from. You can open the `docs/index.html` in your browser to see a local version of the docs generated from your code.

Your change are of course not going to be visible on any other live version of the docs.

Could also try deleting the `./docs` directory, then rerun `make docs`, just to see if that helps.

---

<div class="post-metadata">

**Author:** ![curious2learn](https://avatars.discourse-cdn.com/v4/letter/c/5daacb/32.png) [@curious2learn](https://forum.crystal-lang.org/u/curious2learn)\
**Post date:** [June 23, 2019, 1:40am UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/18 "2019-06-23T01:40:20Z")

</div>

I understood that you were asking me to look at the local version of the docs generated. That is what I am/was looking at.

As you suggested I also tried deleting the `docs` directory in the local `crystal` folder. Running `make docs` generated that directory as expected, but the new version does not contain the example either. Is there any way I can send the `src/openssl/digest/digest.cr` file that I modified, so that you can take a look at the lines where I added the example. Maybe something is wrong with my setup.

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [June 23, 2019, 2:02am UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/19 "2019-06-23T02:02:10Z")

</div>

Just push up your changes and I could look at your branch on your fork.

---

<div class="post-metadata">

**Author:** ![curious2learn](https://avatars.discourse-cdn.com/v4/letter/c/5daacb/32.png) [@curious2learn](https://forum.crystal-lang.org/u/curious2learn)\
**Post date:** [June 23, 2019, 3:30am UTC](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863/20 "2019-06-23T03:30:59Z")

</div>

Thanks for your patience and sorry for so many questions.

I have created a new branch, but I have not forked the `crystal` repo. I just cloned it. Can I just push to the one I cloned from, or do I need to create a fork? `git remote -v` shows this for `push`

```
origin	https://github.com/crystal-lang/crystal.git (push)

```

If I can just push to this one, do I first merge my changes in master before pushing or should I just try to push the branch that I have created (if that is even possible)?

Thanks!

[Next page](https://forum.crystal-lang.org/t/how-to-read-crystal-documentation/863.md?page=2)
