How to properly set an instance variable with instance_variable_set? - ruby-on-rails

I was looking through the docs for instance_variable_set and saw that the sample code given does this:
obj.instance_variable_set(:#instnc_var, "value for the instance variable")
which then allows you to access the variable as #instnc_var in any of the class's instance methods.
I'm wondering why there needs to be a colon : before the #instnc_var. What does the colon do?

My first instinct is to tell you not to use instance_variable_set unless you really know what you are using it for. It's essentially a tool for metaprogramming or a hack to bypass visibility of the instance variable.
That is, if there is no setter for that variable, you can use instance_variable_set to set it anyway. It's far better if you control the code to just create a setter.
Try looking at accessors for the vast majority of your instance variable setting needs. They are an idiomatic way to have getters and setters for your instance variables "for free" without you having to write those functions.
If you really do need instance_variable_set, it allows the first argument to be a symbol which is the name of the instance variable to set. A colon is part of the Ruby language that is like a "symbol literal": when you type :foo, you've created a symbol with value foo, just like when you type "bar" directly into your code, you create a string literal with value "bar".

Related

If a set literal is of type set then what is its class in dart?

So the following code snippet
Set mySet = {1,2,3};
is an instance of type Set which is permissible, however what would the class of the set literal be. I have tried to search for this, however I have found no answer in the dart documentation.
A literal exists only in your source code. Asking for its "class" doesn't make a lot of sense.
Using a Set, Map, or List literal is just syntactic sugar for invoking a corresponding constructor. The Set factory constructor constructs a LinkedHashSet.
However, you'll see that LinkedHashSet is also abstract. Its factory constructor returns an instance of a private, internal class. You can see its typename via print(Set().runtimeType); the actual type might be different for different platforms and is unlikely to be useful to you.

Ruby - Why is it possible to use Instance variables like everywhere

I'm into Ruby on Rails programming for almost 5 weeks now.
I was wondering why people always use instance variables instead of local ones.
I always thought that you would use instance variables only for classes (so these instance variables are the attributes of the class).
But people also use them not only for being attributes of a class. And this is the part where I am getting confused.
For instance, take a look at these lines of codes:
class Foo
def print_a_hello
puts "Hello World"
end
end
#instance_variable = Foo.new
#instance_variable.print_a_hello
# => "Hello World"
locale_variable = Foo.new
locale_variable.print_a_hello
# => "Hello World"
So, who of you got a great explanation for me?
I was wondering why people always use instance variables instead of locale ones.
I'm not sure how you get that impression. I certainly don't "always" use instance variables. I use instance variables when I need an instance variable, and I use local variables, when I need a local variable, and most code I see does it the same way.
Usually, it doesn't even make sense to interchange them. They have completely different purpose: local variables have static lexical scope, instance variables have dynamic object scope. There's pretty much no way to interchange them, except for the very narrow case of a simple single-file procedural script, where the dynamic scope of the top-level main object and the lexical scope of the script body are identical.
I always thought that you would use instance variables only for classes (so these instance variables are the attributes of the class).
No. Instance variables are attributes of the instance (i.e. object), not the class, that's why they are called "instance variables", after all. Class variables are attributes of the class, but class variables are a different beast and only used in very specific circumstances. (Classes are objects (i.e. instances), too, so they can have instance variables as well; there's generally no need to use class variables, which have some weird and un-intuitive properties, unless you specifically need those weird and un-intuitive properties).
For instance, take a look on this short codelines:
class Foo
def print_a_hello
puts "Hello World"
end
end
#instance_variable = Foo.new
#instance_variable.print_a_hello
# => "Hello World"
locale_variable = Foo.new
locale_variable.print_a_hello
# => "Hello World"
This is the case I mentioned above: in this specific case (and only in this case), the dynamic scope of the top-level main object and the static lexical scope of the script body are identical, so it doesn't matter whether you use a local variable of the script body or an instance variable of the main object.
However, if we make just a tiny change to that, by adding a second script and requireing it from the first, that condition will no longer hold, because we now have two separate script bodies and thus two separate script scopes, but still only one top-level object.
The idiomatic way in your example would definitely be to use a local variable, and nobody I know would do otherwise.
Best use case for instance variables is in Controller's when you want to pass parameter to the view.
Then you use something like
class TestController < ActionController::Base
def show
#usable_in_view = Test.first
not_usable_in_view = Test.first
end
end
In your view you can now use #usable_in_view, but cant use variable not_usable_in_view. Most people always use instance variable in controllers even if they do not need them in view, because they do not understand why they need instance variable
Instance variables are used so that they can be accessed in the view page.
Local variables are not accessible in the view. It has become the habit even I sometimes write instance variables though it is not required in the view.:-)
People probably get in the [bad] habit of using instance variables everywhere since it's common in Rails to use them to get information from the controller to the view.
In my own Ruby code I use instance variables only when I need to, local variables otherwise. That's the proper way to use Ruby.

How do I access the Activerecord setter I overrode?

I want to use a custom setter to do some formatting of my fields. In irb if I test the setter like:
o.field_name = "4"
I see that my custom setter is being referred to. But with this it is not:
o[:field_name] = "4"
I understand that in the first case this is a function call and in the second case we are just setting the attribute directly. But I don't completely see how the attribute can be set without going through our custom setter, I thought that was the point.
But my main question is that if var holds my field_name, I don't see how to dynamically refer to a.var and have it be interpreted as a.field_name. All I see to do is a[var] and this bypasses my setter.
Try a.send(var) where var = 'field_name'
That's the equivalent of a.field_name
o[:field_name] is like read_attribute(:field_name), thus is just reads the value as you said. It can be quite important in virtual attributes in order to bypass the stack too deep error. If you do a[:var], you just get its value. A virtual attribute refers to an attribute, if you are setting its value to another variable, you just get its value, not the object.

How to access a base class property (variable) in ironruby?

I'm trying to do some XNA development with IronRuby but are struggling with both generics (Load) and accessing some of the base-class properties such as Content.
Any hints?
Regarding Generics - if you want to create a generic object, use square brackets in order to define the generic type. For example:
list = System::Collections::Generic::List[System::String].new
Regarding base class properties, there is no "base" keyword in Ruby so you can use "self" or just call the method or property directly. You might also try to mangle the property name (for instance, HelloWorld is mangled to hello_world). I suggest that in order to access the Content propery, just call it this way:
self.content
Hope it helps,
Shay.

Regarding F# Object Oriented Programming

There's this dichotomy in the way we can create classes in f# which really bothers me. I can create classes using either an implicit format or an explicit one. But some of the features that I want are only available for use with the implicit format and some are only available for use with the explicit format.
For example:
I can't use let inline* (or let alone) inside an explicitly defined class.
The only way (that I know) to define immutable public fields (not properties*) inside an implicitly defined class is the val bla : bla syntax.
But there's a redundancy here. Since I'll end up with two copy of the same immutable data, one private, one public (because in the implicit mode the constructor parameters persist throughout the class existence)
(Not so relevant) The need to use attributes for method overloading and for field's defaults is rather off putting.
Is there anyway I can work around this?
*For performance reasons
EDIT: Turns out I'm wrong about both points (Thanks Ganesh Sittampalam & MichaelGG).
While I can't use let inline in both implicit & explicit class definition, I can use member inline just fine, which I assume does the same thing.
Apparently with the latest F# there's no longer any redundancy since any parameters not used in the class body are local to the constructor.
Will be gone in the next F# release.
This might not help, but you can make members inline. "member inline private" works fine.
For let inline, you can work around by moving it outside the class and explicitly passing any values you need from inside the scope of the class when calling it. Since it'll be inlined, there'll be no performance penalty for doing this.

Resources