Realize PHP / Python generator with Golang / Ruby

Realize a generator with Golang (Go) / Ruby

[Here](http://qiita.com/hiroykam/items/2fea445fd2d489354c34#%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AC%E3%83%BC%E3 When I was investigating generators in PHP and Python3 with% 82% BF), I investigated how it can be realized in Golang and Ruby.

Generator with PHP, Python3, Golang, Ruby 2.4

I read numbers.txt and prepared a simple generator that produces the following output results.

numbers.txt


zero
one
two
three
four
five

Output result


0:zero
1:one
2:two
3:three
4:four
5:five

For PHP

Verified with PHP 5.6. I didn't select PHP7 because I didn't use yield from this time.

<?php

function my_generator($name)
{
    $file = fopen($name, "r");

    if ($file) {
        while ($line = fgets($file)) {
            yield $line;
        }
    }
    fclose($file);
}

$g = my_generator("numbers.txt");
foreach ($g as $k => $v) {
    print($k. ":". $v);
}

For Python

It can be achieved in the same way as PHP. I used 3.5 version of Python.

def my_generator(name):
    with open(name) as lines:
        for line in lines:
           yield line

g = my_generator("numbers.txt")
for k, v in enumerate(g):
    print("%s:%s" % (k, v), end="")

For Golang

Golang does not have the equivalent of PHP or Python yield (see Reference here). Therefore, a similar thing was achieved by using a goroutine channel or closure.

Method using Goroutine channel

Assuming that the number of lines in numbers.txt is huge, there are performance concerns.

package main

import (
    "bufio"
    "fmt"
    "os"
)

func yield(fp *os.File) chan string {
    ch := make(chan string)

    go func() {
        defer close(ch)

        scanner := bufio.NewScanner(fp)
        for scanner.Scan() {
            ch <- scanner.Text()
        }
        if err := scanner.Err(); err != nil {
            panic(err)
        }
    } ()

    return ch
}

func main() {
    fp, err := os.Open("numbers.txt")
    if err != nil {
        panic(err)
    }
    defer fp.Close()

    i := 0
    for s := range(yield(fp)) {
        fmt.Printf("%d:%s\n", i, s)
        i++
    }
}

Method using closure

There may be a way to synchronize with sync.Mutex.

package main

import (
    "bufio"
    "fmt"
    "os"
)

func yield(fp *os.File) func() (bool, string) {
    scanner := bufio.NewScanner(fp)
    return func() (bool, string) {
        t := scanner.Scan()
        if err := scanner.Err(); err != nil {
            panic(err)
        }
        return t, scanner.Text()
    }
}

func main() {
    fp, err := os.Open("numbers.txt")
    if err != nil {
        panic(err)
    }
    defer fp.Close()

    y := yield(fp)
    for i := 0;;i++ {
        t, s := y()
        if !t { break }
        fmt.Printf("%d:%s\n", i, s)
    }
}

For Ruby 2.4

Ruby also has yield, but it is a function definition that receives blocks instead of a generator like PHP / Python. There is ʻEnumerator` as a function equivalent to the PHP / Python generator, and it is described as follows.

def my_generator(name)
  return to_enum(__method__, name) unless block_given?
  IO.foreach(name) do |line|
    yield(line.chomp)
  end
end

g = my_generator('numbers.txt')
g.with_index { |l, i| p '%d:%s' % [i, l] }

Here, if there is a block, it can be processed as a block, and if there is no block, it can be treated as a method that returns Enumerator.

Recommended Posts

Realize PHP / Python generator with Golang / Ruby
Dynamic proxy with python, ruby, PHP
Overlapping combinations with limits in Python / Ruby / PHP / Golang (Go)
I tried using mecab with python2.7, ruby2.3, php7
Grouping combination in Python / Ruby / PHP / Golang (Go)
Java VS PHP VS Python VS Ruby
Zundokokiyoshi with python / ruby / Lua
About Perl, Python, PHP, Ruby
Handle prime numbers in Python / Ruby / PHP / Golang (Go)
Factorial, permutations, (duplicate) combinations in Python / Ruby / PHP / Golang (Go)
Scraping with Node, Ruby and Python
random French number generator with python
Realize DB connection pool with golang
Handling regular expressions with PHP / Python
Send image with python, save with php
PHP / Python / Ruby sample hitting Path API
[Basic grammar] Differences between Ruby / Python / PHP
Try calling Python from Ruby with thrift
Encrypt with Ruby (Rails) and decrypt with Python
Easy web scraping with Python and Ruby
I tried hitting Mastodon API with Ruby (Faraday) / Python (Pycurl) / PHP (Curl)
FizzBuzz with Python3
Scraping with Python
How to enjoy programming with Minecraft (Ruby, Python)
Statistics with python
Scraping with Python
Python with Go
Twilio with Python
Integrate with Python
[Python] Generator function
Play with 2016-Python
AES256 with python
Tested with Python
python starts with ()
with syntax (Python)
Bingo with python
Zundokokiyoshi with python
Excel with Python
Microcomputer with Python
Cast with python
From the initial state of CentOS8 to running php python perl ruby with nginx
2014 Web Application Framework Trends (PHP / Java / Ruby / Python / Perl)
Note that writing like this with ruby is writing like this with python
A story about trying a (Golang +) Python monorepo with Bazel
Execute python3 system with PHP exec () on AWS EC2
Getting Started with Google App Engine for Python & PHP
python, php, ruby How to convert decimal numbers to n-ary numbers
Let's write Python, Ruby, PHP, Java, JavaScript side respectively
Comparison of CoffeeScript with JavaScript, Python and Ruby grammar
Version control of Node, Ruby and Python with anyenv
How to handle JSON in Ruby, Python, JavaScript, PHP
Serial communication with Python
Zip, unzip with python
Primality test with Python
Python with eclipse + PyDev.
Socket communication with Python
Data analysis with python 2
Scraping with Python (preparation)
Try scraping with Python.
[Docker] Tutorial (Python + php)
Sequential search with Python