Reputation: 1585
Newbie ruby question.
I have a class
class ReportPage < Page
def badge_item(item_int)
case item_int
when 1..50 then @item= 1
when 50..100 then @item= 50
end
def check_completed_items_badge
badge_item(50)
puts @item
end
end
Sure enough, it puts nil. And here comes my question - how can I use @item variable inside of the other method of the class?
Thank you a lot!
Upvotes: 1
Views: 4018
Reputation: 2116
I know an answer has already been accepted but I wanted to present a more general answer to the question about how instance variables get tossed around.
Straight from ruby-lang you get the following:
Ruby needs no variable declarations. It uses simple naming conventions to denote the scope of variables.
- var could be a local variable.
- @var is an instance variable.
- $var is a global variable.
These sigils enhance readability by allowing the programmer to easily identify the roles of each variable. It also becomes unnecessary to use a tiresome self. prepended to every instance member
It is important to understand the distinction between these different types of variables. To do this I whipped up a small example that should help give anyone with navigates here a good starting point on how these behave.
class Scoping
@unreachable = "but found it. trololol"
$instance = "and found it. swag swag"
def initialize( int )
trial = @unreachable ? @unreachable : " but failed to find."
puts "reaching for the unreachable . . ." + trial
@int = int
end
end
puts $instance
Scoping.new 10
trial = @int ? @int : " but failed to find."
puts "Reaching for instance from class . . ." + trial
trial = $instance ? $instance : " but failed to find."
puts "Reaching for global variable . . ." + trial
Upvotes: 0
Reputation: 12588
The correct approach in your case is to use the OOP:
class ReportPage < Page
class BadgeItem
def initialize( int )
fail "Badge item integer should be in the range 0..99!" unless 0..99 === int
@int = int
end
def classify
case @int
when 0...50 then 1
when 50..99 then 50
end
end
end
def check_completed_items_badge
badge_item = BadgeItem.new 50
puts badge_item.classify
end
end
Upvotes: 0
Reputation: 2785
The thing is you miss end
keyword for your case
. And there is another problem in this program. when(1..50)
contain all cases between 1 to 50, and when(50..100)
covers 50 to 100, this will lead confusion cause badge_item(50)
will go into the first line, set @item
to 1
and quit the case ... end
block. So at the end it will print 1
on the screen.
To make your intent more clearly, you should use
def badge_item(item_int)
@item = case item_int
when 1..49 then 1 #two dots, cover 1 to 49
when 50..100 then 50
end
end
OR
def badge_item(item_int)
@item = case
when 1...50 then 1 #three dots between, cover 1 to 49
when 50..100 then 50
end
end
Upvotes: 5
Reputation: 21180
The problem is not with the variable assignment but instead with your usage of the case/when syntax. When you give case an argument it uses exact matching to compare the different scenarios. A better way in your case would probably be to use something like this instead:
def badge_item(item_int)
case
when (1..50).include?(item_int) then @item = 1
when (50..100).include?(item_int) then @item = 50
end
end
Edit
Corrections from Tumtu:
case uses === method to compare values. i.e.: (1..50) === 50
Upvotes: 3