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

Actions adore keyword arguments #174

Merged
merged 3 commits into from
Dec 2, 2016
Merged

Commits on Nov 28, 2016

  1. Actions adore keyword arguments

    Consider this task:
    
    ```ruby
    task :t, [:arg] do |task, arg: 'default_value'|
      emotion = "\e[32m^_^\e[0m"
      emotion = "\e[31mt.t\e[0m" if ARGV[0] =~ /t\[(.*)\]$/ && $1 != arg
      puts "task #{task.name.inspect} got #{arg.inspect} #{emotion}"
    end
    ```
    
    Run this on your machine right now, you'll see the task is in tears.
    But this commit turns tearful eyes into smiling ones, observe:
    
    ```sh
    $ rake t
    task "t" got "default_value" ^_^
    $ rake t[custom_value]
    task "t" got "default_value" t.t
    
    $ ruby -Ilib exe/rake t
    task "t" got "default_value" ^_^
    $ ruby -Ilib exe/rake t[custom_value]
    task "t" got "custom_value" ^_^
    ```
    
    It accomplishes this by always invoking the action in the same way.
    Previously, Rake invoke the action with different argument structures based the arity
    https://github.com/ruby/rake/blob/59856100815b841624269f817c815f54921bf321/lib/rake/task.rb#L251-L256
    
    ```ruby
    case act.arity
    when 1
      act.call(self)
    else
      act.call(self, args)
    end
    ```
    
    I assume it's expecting one of these:
    
    ```ruby
    proc { |task| }.arity           # => 1
    proc { |task, options| }.arity  # => 2
    ```
    
    However this leads numerous task signatures to be invoked incorrectly.
    Eg, consider the case of our tearful task above, here is why it cries.
    
    ```ruby
    proc { |task, arg: 'default_value'| }.arity # => 1
    ```
    
    The solution is nice and easy: always invoke the block the same way.
    Why was this ever a thing at all, then?
    Looks like it was added in 2007 about a month after Ruby 1.8.6 was released.
    ruby@925fbb8
    Probably something was just different back then, eg the difference
    between lambdas and procs was whether you did `prc.call` or `prc.yield`
    https://github.com/ruby/ruby/blob/9b383bd/eval.c#L8356-L8415
    JoshCheek committed Nov 28, 2016
    Configuration menu
    Copy the full SHA
    2511d56 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    57869cd View commit details
    Browse the repository at this point in the history

Commits on Nov 29, 2016

  1. Configuration menu
    Copy the full SHA
    7d664a0 View commit details
    Browse the repository at this point in the history