#Not Understanding Packages

45 messages · Page 1 of 1 (latest)

rain spire
#

Hello fellow Gophers! I am usually one to be able to figure out my own issues with Google, Stack Overflow, or lately even ChatGPT. This time I am truly stumped. I have tried to follow to the best of my understanding the docs. I am following a guide and her code works just fine. I have spent hours Googling and trying to understand but I just cannot.

I have a helper.go inside another module (is my understanding of how modules work) which to my knowledge means they should share my globally defined variables unless I am misunderstanding.

Any help or guidance would be appreciated.

#

My file structure is as follows:

./booking-app
  go.mod
  main.go
  /helper
    go.mod
    helper.go

./booking-app/main.go

package main

import (
    "booking-app/helper"
    "fmt"
    "strings"
)

// Package level variables
const conferenceTickets = 50

var conferenceName string = "Go Conference"
var remainingTickets uint = conferenceTickets
var bookings []string

func main() {
    greetUsers()

    for remainingTickets > 0 && len(bookings) < 50 {
        firstName, lastName, email, userTickets := getUserInput()

        isValidName, isValidEmail, isValidTickets := helper.ValidateUserInput(firstName, lastName, email, userTickets)

        if isValidName && isValidEmail && isValidTickets {
            bookTicket(userTickets, firstName, lastName, email)

            firstNames := getFirstNames()
            fmt.Printf("These are all our bookings: %v\n", firstNames)

            if remainingTickets == 0 {
                // end the program
                fmt.Println("Our conference is now fully booked. Come back next year!")
                break
            }
        } else {
            if !isValidName {
                fmt.Println("First or last name is too short.")
            }

            if !isValidEmail {
                fmt.Println("Your email needs and @ sign.")
            }

            if !isValidTickets {
                fmt.Println("Invalid number of tickets.")
            }
        }
    }
}

func greetUsers() {
    fmt.Printf("Welcome to %s booking application.\n", conferenceName)
    fmt.Printf("We have a total of %d tickets with %d available.\n", conferenceTickets, remainingTickets)
    fmt.Println("Get your tickets here to attend.")
}

func getFirstNames() []string {
    firstNames := []string{}
    for _, booking := range bookings {
        var names = strings.Fields(booking)
        var firstName = names[0]
        firstNames = append(firstNames, firstName)
    }
    return firstNames
}

func getUserInput() (string, string, string, uint) {
    var firstName string
    var lastName string
    var email string
    var userTickets uint

    // take input from the console and assign it to username
    // via the pointer with the & syntax directly assigning
    // the value to memory
    fmt.Println("Enter your first name:")
    fmt.Scan(&firstName)

    fmt.Println("Enter your last name:")
    fmt.Scan(&lastName)

    fmt.Println("Enter your email:")
    fmt.Scan(&email)

    fmt.Println("Enter number of tickets:")
    fmt.Scan(&userTickets)

    return firstName, lastName, email, userTickets
}

func bookTicket(userTickets uint, firstName string, lastName string, email string) {
    remainingTickets = remainingTickets - userTickets
    bookings = append(bookings, firstName+" "+lastName)

    fmt.Printf("Thank you %s %s for booking %d tickets.\n", firstName, lastName, userTickets)
    fmt.Printf("You will recieve a confirmation email soon at %s.\n", email)
    fmt.Printf("%d tickets remaining for %s\n", remainingTickets, conferenceName)
}

./booking-app/go.mod

module booking-app

go 1.19

replace booking-app.com/helper => ./helper

require booking-app.com/helper v0.0.0-00010101000000-000000000000

./booking-app/helper/helper.go

package helper

import (
    "strings"
)

func ValidateUserInput(firstName string, lastName string, email string, userTickets uint) (bool, bool, bool) {
    isValidName := len(firstName) >= 2 && len(lastName) >= 2
    isValidEmail := strings.Contains(email, "@")
        // RemainingTickets - undeclared named
        // [daixso@ashesdev booking-app]$ go run .
        // # booking-app.com/helper
        // helper/helper.go:10:54: undefined:                // RemainingTickets
    isValidTickets := userTickets > 0 && userTickets <= RemainingTickets

    return isValidName, isValidEmail, isValidTickets
}

./booking-app/helper/go.mod

module helper

go 1.19
#

I feel like I have messed with it so much trying to fix it I have just royally screwed it all up. If anyone replied please ping me so I see it!

peak nimbus
#

A module defines a project

#

Thsi looks to be one project

#

So you should have one top level module

rain spire
#

As in a top level package?

peak nimbus
#

Just the root of the project

#

The one you have next to main.go is fine

#

Delete the one in helpers

rain spire
#

Okay I assumed I just needed one so that makes sense I added the other in my many attempts to fix the issue lol

#
[daixso@ashesdev booking-app]$ go run .
go: booking-app.com/[email protected] (replaced by ./helper): reading helper/go.mod: open /home/daixso/go-proj/booking-app/helper/go.mod: no such file or directory
#

after removing the second go.mod I get a new error

peak nimbus
#

You need to remove the extra stuff in the go.mod

#

The replace and require

rain spire
#

Okay those are gone and I now have

[daixso@ashesdev booking-app]$ go run .
main.go:7:2: no required module provides package booking-app.com/helper; to add it:
        go get booking-app.com/helper
peak nimbus
#

Your project import root is your module name

#

booking-app/helper is the import

rain spire
#

Okay another confusion from the research I did trying to fix things

#

Which also makes sense lol

peak nimbus
#

You typically name your module some uri where you can find the modules code

#

That’s probably what got you confused there

rain spire
#

Right like if I had it on github or something

#

Yeah

#
[daixso@ashesdev booking-app]$ go run .
# booking-app/helper
helper/helper.go:10:54: undefined: RemainingTickets
peak nimbus
#

Now to your question, no packages do not implicitly share globals

#

You have to import the package like you have done and then reference the variable with the package name

rain spire
#

Okay so my understanding of package vs global level is flawed from other languages

peak nimbus
#

myPackage.MyVariable

#

The 2nd part of that is that you can’t import from main

#

So helper.go cannot in any way reference anything in package main

rain spire
#

Okay so I need to pass it as an arg versus relying on the package level declaration

peak nimbus
#

Yes

#

That’s generally perfered either way

rain spire
#

I wonder why it works for the instructor that is pretty interesting

#

Shes using 1.17.3 versus me on 1.19.5 so maybe its changed in the 2 major updates

peak nimbus
#

Its not

#

But without it in front of me I couldn’t tell you

rain spire
#

I definitely understand working with limited info lol well I appreciate the help if you're curious this is the chapter of the video I am using to study https://youtu.be/yyUHQIec83I?t=8556

Full Golang Tutorial to learn the Go Programming Language while building a simple CLI application

In this full Golang course you will learn about one of the youngest programming languages that is becoming more and more popular in the cloud engineering world, which is Go or also commonly known as Golang.
You will learn everything you need to g...

▶ Play video
peak nimbus
#

I don’t have time for that sorry

rain spire
#

All good I think you lead me to the knowledge I needed and I greatly appreciate the time and explanation

peak nimbus
#

If yoy watch the video she passes the remaining tickets in as an argument

rain spire
#

Oh maybe I paused to type and didnt get there Facepalm