Skip to content

Instantly share code, notes, and snippets.

@pcreux
Last active June 12, 2018 17:08
Show Gist options
  • Select an option

  • Save pcreux/2f87847e5e4aad37db02 to your computer and use it in GitHub Desktop.

Select an option

Save pcreux/2f87847e5e4aad37db02 to your computer and use it in GitHub Desktop.

Revisions

  1. pcreux revised this gist Sep 24, 2014. 1 changed file with 7 additions and 4 deletions.
    11 changes: 7 additions & 4 deletions pipable.rb
    Original file line number Diff line number Diff line change
    @@ -65,10 +65,10 @@ def pipe(input, *pipeline)
    Mooify = ->(string) { "Cow said: " + string }
    Say = ->(string) { system %|say "#{string}"|; string }

    class TweetTo < Struct.new(:recipient)
    def call(string)
    puts %|Tweeting "#{string}" to #{@recipient}!|
    string
    TweetTo = Struct.new(:recipient) do
    def call(input)
    puts %|Tweeting "#{input}" to #{@recipient}!|
    input
    end
    end

    @@ -97,10 +97,13 @@ def call(string)
    # => Cow said: maaw

    # ZOMG! Multiplexing!
    # "moo" => Mooify => :downcase => Reverse
    # => :upcase => Reverse
    p Pipeline.new(Mooify, [:downcase, :upcase], Reverse).call("moo")
    # => ["oom :dias woc", "OOM :DIAS WOC"]

    # Multi-Multiplexing... let me tell you...
    p Pipeline.new(Mooify, [:downcase, :upcase], Reverse, [:reverse, Leet]).call("moo")
    # => [["cow said: moo", "00m :d145 w0c"], ["COW SAID: MOO", "OOM :DIAS WOC"]]


  2. pcreux revised this gist Sep 24, 2014. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions pipable.rb
    Original file line number Diff line number Diff line change
    @@ -101,6 +101,6 @@ def call(string)
    # => ["oom :dias woc", "OOM :DIAS WOC"]

    # Multi-Multiplexing... let me tell you...
    p Pipeline.new(Mooify, [:downcase, :upcase], Reverse, [:reverse, :capitalize]).call("moo")
    # => [["cow said: moo", "Oom :dias woc"], ["COW SAID: MOO", "Oom :dias woc"]]
    p Pipeline.new(Mooify, [:downcase, :upcase], Reverse, [:reverse, Leet]).call("moo")
    # => [["cow said: moo", "00m :d145 w0c"], ["COW SAID: MOO", "OOM :DIAS WOC"]]

  3. pcreux revised this gist Sep 24, 2014. 1 changed file with 9 additions and 8 deletions.
    17 changes: 9 additions & 8 deletions pipable.rb
    Original file line number Diff line number Diff line change
    @@ -11,23 +11,24 @@

    # Ugly implementation starts here...

    def pipe_it(input, other)
    def pipe_it(input, filter)
    # multiplexed input!
    if input.is_a? Array
    return input.map { |element| pipe_it(element, other) }
    return input.map { |input_item| pipe_it(input_item, filter) }
    end

    case other
    case filter
    when Symbol
    input.send(other)
    input.send(filter)
    when Hash
    method = other.keys.first
    arguments = Array(other.values.first)
    method = filter.keys.first
    arguments = Array(filter.values.first)
    input.send(method, *arguments)
    when Array
    # multiplex!
    other.map { |element| pipe_it(input, element) }
    filter.map { |filter_item| pipe_it(input, filter_item) }
    else
    other.call(input)
    filter.call(input)
    end
    end

  4. pcreux revised this gist Sep 24, 2014. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions pipable.rb
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    # Elixir as pipes `|>`. Let's try to implement those in Ruby.
    # Elixir has pipes `|>`. Let's try to implement those in Ruby.
    #
    # I want to write something like this:
    # I want to write this:
    #
    # email.body | RemoveSignature | HighlightMentions | :html_safe
    #
  5. pcreux revised this gist Sep 24, 2014. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions pipable.rb
    Original file line number Diff line number Diff line change
    @@ -98,3 +98,8 @@ def call(string)
    # ZOMG! Multiplexing!
    p Pipeline.new(Mooify, [:downcase, :upcase], Reverse).call("moo")
    # => ["oom :dias woc", "OOM :DIAS WOC"]

    # Multi-Multiplexing... let me tell you...
    p Pipeline.new(Mooify, [:downcase, :upcase], Reverse, [:reverse, :capitalize]).call("moo")
    # => [["cow said: moo", "Oom :dias woc"], ["COW SAID: MOO", "Oom :dias woc"]]

  6. pcreux revised this gist Sep 24, 2014. 1 changed file with 11 additions and 0 deletions.
    11 changes: 11 additions & 0 deletions pipable.rb
    Original file line number Diff line number Diff line change
    @@ -12,13 +12,20 @@
    # Ugly implementation starts here...

    def pipe_it(input, other)
    if input.is_a? Array
    return input.map { |element| pipe_it(element, other) }
    end

    case other
    when Symbol
    input.send(other)
    when Hash
    method = other.keys.first
    arguments = Array(other.values.first)
    input.send(method, *arguments)
    when Array
    # multiplex!
    other.map { |element| pipe_it(input, element) }
    else
    other.call(input)
    end
    @@ -87,3 +94,7 @@ def call(string)

    puts pipeline.call("moo")
    # => Cow said: maaw

    # ZOMG! Multiplexing!
    p Pipeline.new(Mooify, [:downcase, :upcase], Reverse).call("moo")
    # => ["oom :dias woc", "OOM :DIAS WOC"]
  7. pcreux revised this gist Sep 24, 2014. 1 changed file with 40 additions and 20 deletions.
    60 changes: 40 additions & 20 deletions pipable.rb
    Original file line number Diff line number Diff line change
    @@ -11,31 +11,43 @@

    # Ugly implementation starts here...

    def pipe_it(obj, other)
    def pipe_it(input, other)
    case other
    when Symbol
    obj.send(other)
    input.send(other)
    when Hash
    method = other.keys.first
    arguments = Array(other.values.first)
    obj.send(method, *arguments)
    input.send(method, *arguments)
    else
    other.call(obj)
    other.call(input)
    end
    end

    def Pipe(*args)
    args.inject do |obj, other|
    pipe_it(obj, other)
    class Pipeline
    def initialize(*filters)
    @filters = filters
    end

    attr_accessor :filters

    def call(input)
    filters.inject(input) do |input, filter|
    pipe_it(input, filter)
    end
    end
    end

    def pipable(obj)
    obj.define_singleton_method(:|) do |other|
    pipable pipe_it(obj, other)
    def pipable(input)
    input.define_singleton_method(:|) do |filter|
    pipable pipe_it(input, filter)
    end

    obj
    input
    end

    def pipe(input, *pipeline)
    Pipeline.new(*pipeline).call(input)
    end

    # Let's define a few filters
    @@ -45,25 +57,33 @@ def pipable(obj)
    Mooify = ->(string) { "Cow said: " + string }
    Say = ->(string) { system %|say "#{string}"|; string }

    def TweetTo(recipient)
    TweetTo.new(recipient)
    end

    class TweetTo < Struct.new(:recipient)
    def call(string)
    puts %|Tweeting "#{string}" to #{@recipient}!|
    string
    end
    end

    # Time to play with it!
    # Time to play with different approaches...

    # We make the first element pipable and we can then just pipe through!
    result = pipable("moo") | Reverse | Leet | Mooify | :downcase | TweetTo('@pcreux') | { delete: 'o' }
    # 1 - We make the first element pipable and we can then just pipe through!
    result = pipable("moo") | Reverse | Leet | Mooify | :downcase | TweetTo.new('@pcreux') | { delete: 'o' }
    puts result
    # => cw said: 00m

    # No syntactic sugar here so that we don't define the singleton method `|`
    puts Pipe("moo", Mooify, :upcase)
    # 2 - Pipe without defining any `|` method
    puts pipe("moo", Mooify, :upcase)
    # => COW SAID: MOO

    # 3 - Pipeline object
    pipeline = Pipeline.new(Mooify, :downcase, { gsub: ["o", "a"] })

    pipeline.filters << ->(input) { input.gsub("moo", "maow") }

    puts pipeline.call("moo")
    # => caw said: maa

    pipeline.filters.reverse!

    puts pipeline.call("moo")
    # => Cow said: maaw
  8. pcreux revised this gist Sep 24, 2014. 1 changed file with 11 additions and 1 deletion.
    12 changes: 11 additions & 1 deletion pipable.rb
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,12 @@
    # Let's try to implement sexy pipes as they have in Elixir
    # Elixir as pipes `|>`. Let's try to implement those in Ruby.
    #
    # I want to write something like this:
    #
    # email.body | RemoveSignature | HighlightMentions | :html_safe
    #
    # instead of:
    #
    # HighlightMentions.call(RemoveSignature.call(email.body)).html_safe
    #

    # Ugly implementation starts here...
    @@ -50,10 +58,12 @@ def call(string)

    # Time to play with it!

    # We make the first element pipable and we can then just pipe through!
    result = pipable("moo") | Reverse | Leet | Mooify | :downcase | TweetTo('@pcreux') | { delete: 'o' }
    puts result
    # => cw said: 00m

    # No syntactic sugar here so that we don't define the singleton method `|`
    puts Pipe("moo", Mooify, :upcase)
    # => COW SAID: MOO

  9. pcreux revised this gist Sep 24, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion pipable.rb
    Original file line number Diff line number Diff line change
    @@ -30,7 +30,7 @@ def pipable(obj)
    obj
    end

    # Let's define some transformations
    # Let's define a few filters

    Reverse = ->(string) { string.reverse }
    Leet = ->(string) { string.gsub(/[aeiost]/,'a'=>'4','e'=>'3','i'=>'1','o'=>'0','s'=>'5','t'=>'7') }
  10. pcreux revised this gist Sep 24, 2014. 1 changed file with 6 additions and 0 deletions.
    6 changes: 6 additions & 0 deletions pipable.rb
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,8 @@
    # Let's try to implement sexy pipes as they have in Elixir
    #

    # Ugly implementation starts here...

    def pipe_it(obj, other)
    case other
    when Symbol
    @@ -28,6 +30,8 @@ def pipable(obj)
    obj
    end

    # Let's define some transformations

    Reverse = ->(string) { string.reverse }
    Leet = ->(string) { string.gsub(/[aeiost]/,'a'=>'4','e'=>'3','i'=>'1','o'=>'0','s'=>'5','t'=>'7') }
    Mooify = ->(string) { "Cow said: " + string }
    @@ -44,6 +48,8 @@ def call(string)
    end
    end

    # Time to play with it!

    result = pipable("moo") | Reverse | Leet | Mooify | :downcase | TweetTo('@pcreux') | { delete: 'o' }
    puts result
    # => cw said: 00m
  11. pcreux revised this gist Sep 24, 2014. 1 changed file with 31 additions and 14 deletions.
    45 changes: 31 additions & 14 deletions pipable.rb
    Original file line number Diff line number Diff line change
    @@ -1,22 +1,28 @@
    # Let's try to implement sexy pipes as they have in Elixir
    #

    def pipe_it(obj, other)
    case other
    when Symbol
    obj.send(other)
    when Hash
    method = other.keys.first
    arguments = Array(other.values.first)
    obj.send(method, *arguments)
    else
    other.call(obj)
    end
    end

    def Pipe(*args)
    args.inject do |obj, other|
    if other.is_a? Symbol
    pipable obj.send(other)
    else
    pipable other.call(obj)
    end
    pipe_it(obj, other)
    end
    end

    def pipable(obj)
    obj.define_singleton_method(:|) do |other|
    if other.is_a? Symbol
    pipable obj.send(other)
    else
    pipable other.call(self)
    end
    pipable pipe_it(obj, other)
    end

    obj
    @@ -27,10 +33,21 @@ def pipable(obj)
    Mooify = ->(string) { "Cow said: " + string }
    Say = ->(string) { system %|say "#{string}"|; string }

    result = pipable("moo") | Reverse | Leet | Mooify | :downcase
    def TweetTo(recipient)
    TweetTo.new(recipient)
    end

    class TweetTo < Struct.new(:recipient)
    def call(string)
    puts %|Tweeting "#{string}" to #{@recipient}!|
    string
    end
    end

    result = pipable("moo") | Reverse | Leet | Mooify | :downcase | TweetTo('@pcreux') | { delete: 'o' }
    puts result
    # => cow said: 00m
    # => cw said: 00m

    puts Pipe("moo", Mooify, Say, :downcase)
    # => cow said: moo
    puts Pipe("moo", Mooify, :upcase)
    # => COW SAID: MOO

  12. pcreux revised this gist Sep 24, 2014. 1 changed file with 27 additions and 7 deletions.
    34 changes: 27 additions & 7 deletions pipable.rb
    Original file line number Diff line number Diff line change
    @@ -1,16 +1,36 @@
    def Pipe(obj)
    # Let's try to implement sexy pipes as they have in Elixir
    #
    def Pipe(*args)
    args.inject do |obj, other|
    if other.is_a? Symbol
    pipable obj.send(other)
    else
    pipable other.call(obj)
    end
    end
    end

    def pipable(obj)
    obj.define_singleton_method(:|) do |other|
    Pipe other.call(self)
    if other.is_a? Symbol
    pipable obj.send(other)
    else
    pipable other.call(self)
    end
    end

    obj
    end

    Reverse = ->(string) { string.reverse }
    Capitalize = ->(string) { string.capitalize }
    Funnify = ->(string) { "ZOMG " + string }
    Reverse = ->(string) { string.reverse }
    Leet = ->(string) { string.gsub(/[aeiost]/,'a'=>'4','e'=>'3','i'=>'1','o'=>'0','s'=>'5','t'=>'7') }
    Mooify = ->(string) { "Cow said: " + string }
    Say = ->(string) { system %|say "#{string}"|; string }

    result = Pipe("moo") | Reverse | Capitalize | Funnify
    result = pipable("moo") | Reverse | Leet | Mooify | :downcase
    puts result
    # => ZOMG Oom
    # => cow said: 00m

    puts Pipe("moo", Mooify, Say, :downcase)
    # => cow said: moo

  13. pcreux revised this gist Sep 11, 2014. 1 changed file with 8 additions and 10 deletions.
    18 changes: 8 additions & 10 deletions pipable.rb
    Original file line number Diff line number Diff line change
    @@ -1,18 +1,16 @@
    module Pipeable
    def |(other)
    other.call(self)
    def Pipe(obj)
    obj.define_singleton_method(:|) do |other|
    Pipe other.call(self)
    end
    end

    class String
    include Pipeable
    obj
    end

    Reverse = ->(string) { string.reverse }
    Reverse = ->(string) { string.reverse }
    Capitalize = ->(string) { string.capitalize }
    Funnify = ->(string) { "ZOMG " + string }

    result = "moo" | Reverse | Capitalize | Reverse
    result = Pipe("moo") | Reverse | Capitalize | Funnify
    puts result
    # => moO

    # => ZOMG Oom

  14. pcreux created this gist Sep 11, 2014.
    18 changes: 18 additions & 0 deletions pipable.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,18 @@
    module Pipeable
    def |(other)
    other.call(self)
    end
    end

    class String
    include Pipeable
    end

    Reverse = ->(string) { string.reverse }
    Capitalize = ->(string) { string.capitalize }

    result = "moo" | Reverse | Capitalize | Reverse
    puts result
    # => moO