Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added :default_formatter option parameter and Membrane.Time.pretty_du… #134

Merged
merged 6 commits into from
Jan 4, 2019

Conversation

mat-hek
Copy link
Member

@mat-hek mat-hek commented Dec 14, 2018

…ration/1

@@ -189,6 +189,8 @@ defmodule Membrane.Element.Base.Mixin.CommonBehaviour do
For others typespec is set to `t:any/0`
* `default:` default value for option. If not present, value for this option
will have to be provided each time options struct is created
* `default_formatter:` function converting value provided as `default` to string.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to a string

@@ -189,6 +189,8 @@ defmodule Membrane.Element.Base.Mixin.CommonBehaviour do
For others typespec is set to `t:any/0`
* `default:` default value for option. If not present, value for this option
will have to be provided each time options struct is created
* `default_formatter:` function converting value provided as `default` to string.
Used upon creating documentation instead of `inspect/1`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'upon' sounds weird to me, I don't think it's the correct word. How about when?

@@ -203,8 +205,11 @@ defmodule Membrane.Element.Base.Mixin.CommonBehaviour do

default_val_desc =
if Keyword.has_key?(v, :default) do
default_formatter =
v |> Keyword.get(:default_formatter, quote(do: &"`#{inspect(&1)}`"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it should be allowed to use formatter producing string without backticks? I think they should be enforced and therefore placed inside a string on line 212. This default value would be simplified to &inspect/1

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backticks suggest that there's a term between them, while formatter may return kind of description of what the default value is, which may not be a term. For example '2 ms' returned by Membrane.Time.pretty_duration/1 shouldn't be considered a term to me.

@@ -60,6 +60,34 @@ defmodule Membrane.Time do
"""
defguard is_native_t(value) when is_integer(value)

@doc """
Returns duration as a string with unit. Chosen unit is the biggest possible one
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one at the end seems redundant


## Examples

iex> 10 |> #{inspect(__MODULE__)}.milliseconds() |> #{inspect(__MODULE__)}.pretty_duration()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can format the tests a bit nicer:

      iex> 10
      ...> |> #{inspect(__MODULE__)}.milliseconds()
      ...> |> #{inspect(__MODULE__)}.pretty_duration()
      "10 ms"

      iex> 60_000_000
      ...> |> #{inspect(__MODULE__)}.microseconds()
      ...> |> #{inspect(__MODULE__)}.pretty_duration()
      "1 min"

iex> 10 |> #{inspect(__MODULE__)}.milliseconds() |> #{inspect(__MODULE__)}.pretty_duration()
"10 ms"
iex> 60_000_000 |> #{inspect(__MODULE__)}.microseconds() |> #{inspect(__MODULE__)}.pretty_duration()
"1 min"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a test for days like this to at least ensure the whole array is traversed:

      iex> 6
      ...> |> #{inspect(__MODULE__)}.days()
      ...> |> #{inspect(__MODULE__)}.pretty_duration()
      "6 d"

"""
@spec pretty_duration(t) :: String.t()
def pretty_duration(time) when is_t(time) do
[ns: 1000, us: 1000, ms: 1000, s: 60, min: 60, h: 24]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we've discussed, I don't like this function very much, but it's OK. Anyway, here's my solution:

  def pretty_duration(time) when is_t(time) do
    [ns: 1, us: 1000, ms: 1000, s: 1000, min: 60, h: 60, d: 24]
    |> Enum.scan(fn {unit, mult}, {_, acc} -> {unit, acc * mult} end)
    |> Enum.reverse()
    |> Enum.find_value(fn {unit, divisor} ->
      rem(time, divisor) == 0 && "#{time |> div(divisor)} #{unit}"
    end)
  end

I know it's a bit less efficient, but takes half of the lines compared to yours 😛
Do whatever you want with it 😄

@bblaszkow06
Copy link
Member

bblaszkow06 commented Dec 17, 2018 via email

@mat-hek
Copy link
Member Author

mat-hek commented Dec 17, 2018

Backticks are not just for terms but for anything you want to present using monospace font. In docs I usually put values like this in backticks. In this case I would also use them to keep the style for different options cosistent. Anyway, It's a matter of opinion so we probably need a 3rd vote 😉

@bblaszkow06 I think that it's not really important whether the font is monospaced or not in this case, but it's important to mark terms so they could be easily distinguished from usual words

@bblaszkow06 bblaszkow06 self-requested a review December 19, 2018 14:56
keyword: [spec: quote_expr(keyword)],
struct: [spec: quote_expr(struct)],
caps: [spec: quote_expr(struct)],
time: [spec: quote_expr(Time.t()), inspector: &Time.pretty_duration/1]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although this pretty_duration is ok, I don't think it is a good way to present the default value. IMHO it should present the call to (Time.some_unit) because otherwise, it would be quite misleading

@@ -50,6 +50,16 @@ defmodule Membrane.Time do
@type non_neg_t :: non_neg_integer
@type native_t :: integer

@units %{
days: :d,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why the units are atoms, not strings?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need only one colon instead of a pair of quotes :D

quote do 2 |> #{inspect(__MODULE__)}.nanoseconds() end |> Macro.to_string()

"""
@spec pretty_duration(t) :: Macro.t()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copy paste went wrong :(

@@ -50,6 +50,16 @@ defmodule Membrane.Time do
@type non_neg_t :: non_neg_integer
@type native_t :: integer

@units %{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This name clashes with units function. If the values here were strings I would name it time_unit_suffixes or sth like that. You may also consider some other name for units function.

@mat-hek mat-hek requested review from bblaszkow06 and removed request for bblaszkow06 December 21, 2018 13:59
@mat-hek mat-hek merged commit ce96116 into master Jan 4, 2019
@bblaszkow06 bblaszkow06 deleted the feature/default-formatter branch February 15, 2019 10:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants