Figuring out func as parameter #185
-
Hi, After weeks of searching something similar I found this on Reddit and looks promising for my project but after hours of trying and checking the source code for examples, I was getting stuck... This is a good example of what I want but I can't use func as parameters by default: package main
import (
"fmt"
"sync"
)
// Crawler represents a generic crawler
type Crawler struct {
Response string
Status int
}
// CrawlerRegistry is responsible for registering and calling crawlers
type CrawlerRegistry struct {
crawlers map[string]func(crawler *Crawler, query string)
mutex sync.RWMutex
}
// NewCrawlerRegistry creates a new instance of CrawlerRegistry
func NewCrawlerRegistry() *CrawlerRegistry {
return &CrawlerRegistry{
crawlers: make(map[string]func(crawler *Crawler, query string)),
}
}
// Register registers a new crawler with the given name and callback function
func (cr *CrawlerRegistry) Register(name string, callback func(crawler *Crawler, query string)) {
cr.mutex.Lock()
defer cr.mutex.Unlock()
cr.crawlers[name] = callback
}
// Call invokes the registered crawler with the given name and query
func (cr *CrawlerRegistry) Call(name string, query string) *Crawler {
cr.mutex.RLock()
defer cr.mutex.RUnlock()
if callback, ok := cr.crawlers[name]; ok {
crawler := &Crawler{}
callback(crawler, query)
return crawler
}
return nil
}
func main() {
// Create a new crawler registry
app := NewCrawlerRegistry()
// Register a crawler for "google"
app.Register("google", func(crawler *Crawler, query string) {
// This is just an example, you can replace it with your actual crawler logic
crawler.Response = fmt.Sprintf("Crawling data from Google for query: %s", query)
crawler.Status = 200
})
// Call the registered crawler with query "animals"
result := app.Call("google", "animals")
// Print the response and status
if result != nil {
fmt.Printf("Response: %s\n", result.Response)
fmt.Printf("Status: %d\n", result.Status)
} else {
fmt.Println("Crawler not found")
}
}
I tried different things like the code below, but everything failed. Firstly I tried with multiple return values in .Register() but I think the language doesn't supporting it. name, errObj := object.AsString(args[0])
if errObj != nil {
return errObj
}
fnRes, isFnRes := args[1].(*object.Function)
if !isFnRes {
return object.NewError(errors.New("expected second arg to be a function"))
}
callFn, hasCallFn := object.GetCallFunc(ctx)
if !hasCallFn {
return object.NewError(errors.New("no callFn found in context"))
} |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
Hi @marianvlad, I can definitely help with this. I'm going to be AFK for most of today but will follow up on this soon. There are a few approaches that will work I think. One would be to wrap the CrawlerRegistry with a Risor It's fairly easy to implement the Risor Regarding passing around callable functions, the I'll follow up soon though and share some concrete code. |
Beta Was this translation helpful? Give feedback.
-
@marianvlad - here is a gist that hopefully helps: https://gist.github.com/myzie/601cf170f88b09efd2012ea322a80259 Let me know what you think. |
Beta Was this translation helpful? Give feedback.
@marianvlad - here is a gist that hopefully helps:
https://gist.github.com/myzie/601cf170f88b09efd2012ea322a80259
Let me know what you think.