0

Please don't judge me too harshly because I am so new to this topic that I don't know how to ask the question (or what to search to get answers):

I am learning nested forms in Sinatra, but encountered something I don't understand which relates to Ruby.

See the code snippet below--while trying to test the code in rake console, I typed in Team, and was surprised to see an object created with the name "Team". But if I type in my_team = Team.new(params), I get an error message that undefined local variable or method 'params' for main:Object

If I typed in anything else, say 'man', I get NameError: undefined local variable or method 'man' for main:Object

Why does the name of the class result in an instance of the class? Shouldn't it require Class_name.new to create an object?

class Team

  attr_accessor :name
    TEAM = []

    def initialize(params)
      @name = params[:team][:name]
      TEAM << self
    end

    def self.all
      TEAM
    end
end

2 Answers 2

2

In Ruby, everything is an object, thus classes are objects (and they are instances of the class Class.

Team is an instance of the class Class (shortened as "a class") whereas Team.new builds an instance of Team. Instances of Class have a certain behavior, which allows to create instances of themselves via the method #new.

Now, any arguments passed to a method in ruby must be defined in your current binding meaning that if params is undefined, you are not allowed to do Team.new(params) right off the bat. Defining a local variable (that will go into the binding) before accessing it is easy :

params = { team: { name: 'StackOverflow' } }
Team.new(params)

will work.

Sign up to request clarification or add additional context in comments.

1 Comment

The distinction btw "an instance of the class Class" and "an instance of a class" explains what was happening. That's why after I typed Team, I could do Team.name and get "Team", but nothing else (such as Team.all) worked. Also thanks for the eg for using 'params'.
1

I loaded that code snippet into irb and Team does not return an instance of the class Team.

The parameter you pass in (params) when you instantiate Team has to BE something; if params is not currently a local variable assigned to an object, ruby will refuse to instantiate Team.

When you're working with a framework like Rails or Sinatra, params is a hash that the Client (your browser) sends to your app inside a HTTP request. In this case, when the params hash hits your app, it would look something like:

{:team => {:name => "Team 1's name"}}

What is probably happening in your app is that user clicks a button like "Create Team" in the browser, and the data entered into that form, such as 'Team Name', is put into the params hash.

If you just took the pure Ruby code that you've provided and just did Team.new(params), that would be the equivalent of Team.new(nil) if params wasn't assigned to anything.

By the way, that's a pretty cool piece of Ruby - it allows you to do Team.all to return an array of previously created Teams.

.all is a Class Method. If you want to understand more about Class Methods, I have a little blog post on it.

Hope all that helps? Feel free to ask more questions if you want.

3 Comments

Thanks for the blog post--a lot of useful conceptual examples. I am going to look through the rest of my code and see if Team.new(nil) is the problem with my Views files.
I think it's a good idea to always post a link to your github repo so people can properly have a poke around the code and get it working for you. Do you have a link to it?
I do have a link, but the code is 'primitive' (& messed up), so I didn't think it'd be worth anybody's time to sift through: github.com/CodeByLine/sinatra-nested-forms-lab-superheros-v-000

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.