What does the "self" keyword references in this Ruby case? - arrays

I would like some help understanding what does self refers to in this case. I understand that self refers to the class, module, etc that "owns" the code currently executing. In my example, my_each is an instance method for the Enumerable module. I'd like to know how does the self keyword works so that when I pass it to my example array it references it.
module Enumerable
def my_each
i = 0
while i < self.size
yield(self[i])
i += 1
end
self
end
end
[2,4,5].my_each { |i|
puts i
}
=> 2
=> 4
=> 5

What self refers to depends on the context. In your case, in an instance method, self refers to the object receiver of your instance method, so in your case the array [2, 4, 5].
But self can refer to other objects too. For example,
class Foo
puts self
end
prints Foo because in that context self refers to the class object. And that's why the two following definitions are the same thing
class Foo
def Foo.m
end
end
class Foo
def self.m
end
end

In Ruby it's all about self and every method is always executed against a particular self.
In your example instance method my_each self will refer to an instance which is using the method.
As you said self can also refer to a class, module..
It is a very powerfull ruby keyword since it can be used to create metaclasses.
If you are interested in understanding more I suggest you read chapter 5 in The Well Grounded Rubyist

self is a special variable that points to the object that "owns" the currently executing code. Ruby uses self everywhere:
For instance variables: #myvar
For method and constant lookup
When defining methods, classes and modules.
Inside of an instance method
In the code below, reflect is an instance method. It belongs to the object we created via Event.new. So self points to that object.
class Event
def reflect
self
end
end
g = Event.new
g.reflect == g # => true
Inside of a class method
For this example, reflect is a class method of Ghost. With class methods, the class itself "owns" the method. self points to the class.
class Event
def self.reflect
self
end
end
Event.reflect == Event # => true
It works the same with "class" methods inside of modules. For example:
module Event
def self.reflect
self
end
end
Event.reflect == Event # => true
Remember, classes and modules are treated as objects in Ruby. So this behavior isn't that different from the instance method behavior we saw in the first example.
Inside of a class or module definition
One feature of Ruby that makes it such a good fit for frameworks like Rails is that you can execute arbitrary code inside class and module definitions. When you put code inside of a class/module definition, it runs just like any other Ruby code. The only real difference is the value of self.
As you can see below, self points to the class or module that's in the process of being defined.
class Event
self == Event # => true
end
module Join
self == Join # => true
end
Inside mixin methods
Mixed-in methods behave just like "normal" instance or class methods when it comes to self. This makes sense. Otherwise the mixin wouldn't be able to interact with the class you mixed it into.
Instance methods
Even though the reflect method as defined in the module, its self is the instance of the class it was mixed into.
module Reflection
def reflect
self
end
end
class Event
include Reflection
end
g = Event.new
g.reflect == g # => true
Class methods
When we extend a class to mix in class methods, self behaves exactly like it does in normal class methods.
module Reflection
def reflect
self
end
end
class Event
extend Reflection
end
Event.reflect == Event # => true
Inside the metaclass
Chances are you've seen this popular shortcut for defining lots of class methods at once.
class Event
class << self
def method1
end
def method2
end
end
end
The class << foo syntax is actually pretty interesting. It lets you access an object's metaclass - which is also called the "singleton class" or "eigenclass." I plan on covering metaclasses more deeply in a future post. But for now, you just need to know that the metaclass is where Ruby stores methods that are unique to a specific object.
If you access self from inside the class << foo block, you get the metaclass.
class << "test"
puts self.inspect
end
# => #<Class:#<String:0x007f8de283bd88>
Outside of any class
If you're running code outside of any class, Ruby still provides self. It points to "main", which is an instance of Object:
puts self.inspect # => main

Related

Is it possible to make a create which returns a boolean

hi i dont know if i asked the question clearly.
i have a deferred class "animal" which contains two features : "bite" (this returns a boolean -> bite:BOOLEAN) and "speak"(speak(word:BOOLEAN)).
now i made a class named "dog" what inherit from "animal". i redefined the two features without a compiler error. now i want to make a create, which contains the function bite (create bite:BOOLEAN).
this gaves me a compiler error, if i try it with the other feature it works fine.
my error code : VGCP(2) creators part lists improper identifier.
thank u for ur help
My Application.e:
note
description : "root class of the application"
date : "$Date$"
revision : "$Revision$"
class
APPLICATION
inherit
ARGUMENTS_32
create
make
feature
d1:DOG
feature {NONE} -- Initialization
make
-- Run application.
do
print(d1.bite)
print ("Hello Eiffel World!%N")
end
end
my animal class:
deferred class
ANIMAL
feature
bite_:BOOLEAN
deferred
end
feature
speak(word:BOOLEAN)
deferred
end
end
my dog class:
class
DOG
inherit
ANIMAL
redefine
bite_,speak_
end
create
bite_
feature
bite_:BOOLEAN
do
Result:=5<3
end
feature
speak(word:BOOLEAN)
do
print("yes")
end
I'm not sure what is the intended semantics of feature speak, so I'll focus solely on feature bite, or, to express the supposed intention better can_bite. Class ANIMAL is similar to what you have:
deferred class
ANIMAL
feature -- Status report
can_bite: BOOLEAN
-- Can this animal bite?
deferred
end
end
With class DOG, two variations are possible: when every dog bites (possibly, depending on some internal state), when the ability to bite is set at object creation time.
In the first scenario, can_bite is a function and the class looks like
class
DOG
inherit
ANIMAL
feature -- Status report
can_bite: BOOLEAN
-- Can this animal bite?
do
Result := True -- It could also be some expression.
end
end
In the second scenario, can_bite is an attribute initialized by a creation procedure, and the class looks like
class
DOG
inherit
ANIMAL
create
make
feature {NONE} -- Creation
make (is_biting: BOOLEAN)
-- Initialize with ability `is_biting`.
do
can_bite := is_biting
end
feature -- Status report
can_bite: BOOLEAN
-- Can this animal bite?
end
Note that in both cases the client has to create the dog object before making any calls on it. In the first case, the default creation procedure is used, and the client code looks like
create d1
print (d1.can_bite)
In the second case, the specific creation procedure is used (it initializes can_bite), and the client code looks like
create d1.make (True)
print (d1.can_bite)

Matlab OOP array of objects class

I'd like to understand how Matlab works with array objecs. I've read several posts and the Matlab help for this topic, but I still don't understand it completely.
Let's take a use case: I'd like to manage several measurement channels (the amount of channels can vary). Each measurement channel is an object with several properties. Now I'd like to have a class handling the channels (channelHandler.m). In this class I can simply add a new channel to the array (later on there might be bore functionality).
So what I've tried so far:
1) create the measurementChannel.m class
In the constructor I've only set the channel name so far without data.
classdef measurementChannel
%CHANNEL holds an instance of a single channel
properties
channelData
channelName = strings
channelUnit = strings
channelDataLength
channelOriginMeasurementFile
end
methods
function obj = channelTest(channelName)
if nargin > 0
obj.channelName = channelName;
end
end
end
end
To test this class I tried this:
channel(1) = measurementChannel('channelA');
channel(2) = measurementChannel('channelB');
channel(1).channelName
channel(2).channelName
which was working well.
2) Now I've created the channelHandler class:
classdef channelHandler
properties (Access = public)
channelArray
end
methods (Access = public)
function addChannel(obj, Name)
testobj = measurementChannel();
testobj.channelName = Name;
obj.channelArray = [obj.channelArray testobj];
end
end
and access this by using the following commands:
createChannels = channelHandler();
createChannels.addChannel('channel1');
createChannels.addChannel('channel2');
createChannels.channelArray(1).channelName
createChannels.channelArray(2).channelName
this fails because channelArray is not defined as an array and will give an error accessing channelArray(2).
So I also tried to initialize the array (but then I need to know the amount of channels).
so my questions are:
a) do I really need to initialize an array of objects?
b) how can I fix the channelHandler class to add objects to the array?
The issue is that you are not inheriting from the handle class and therefore the modifications made within addChannel alter a copy of your object rather than the object itself. If you inherit from handle, the code that you have pasted will work just fine.
classdef channelHandler < handle

Alias module`s method in C(Ruby Extension)

I can`t alias method "dump" from Marshal module
#include "ruby.h"
VALUE Marshal = Qnil;
void Init_test(){
Marshal = rb_define_module("Marshal");
rb_define_alias(Marshal, "hal_dump", "dump");//No error, but don`t work
}
In ruby:
require './test'
p Marshal.methods.grep(/dump/).sort #[:dump]
How i can do alias?
Your C code is similar to the following Ruby code:
module Marshal
alias hal_dump dump
end
dump is a singleton method but also a private instance method (that combination is a so-called module function). You only define an alias of the private instance method.
p Marshal.private_instance_methods.grep(/dump/) # => [:dump, :hal_dump]
That's also why you don't get an error. However you want to define an alias of the singleton method. That can be done by opening the singleton class. A corrected Ruby version might look like this:
p Marshal.methods.grep(/dump/) # => [:dump]
class << Marshal
alias hal_dump dump
end
p Marshal.methods.grep(/dump/) # => [:dump, :hal_dump]
The MRI C API implements the rb_singleton_class() function. It returns the singleton class and can be used like this to fix your code:
rb_define_alias(rb_singleton_class(Marshal), "hal_dump", "dump");

App Engine multiple namespaces

Recently there's been some data structure changes in our app, and we decided to use namespaces to separate different versions of of the data, and a mapreduce task that converts old entities to the new format.
Now that's all fine, but we don't want to always isolate the entire data set we have. The biggest part of our data is stored in a kind that's pretty simple and doesn't need to change often. So we decided to use per-kind namespaces.
Something like:
class Author(ndb.model.Model):
ns = '2'
class Book(ndb.model.Model):
ns = '1'
So, when migrating to version 2, we don't need to convert all our data (and copy all 'Book' kinds to the other namespace), only entities of the 'Author' kind. Then, instead of defining the appengine_config.namespace_manager_default_namespace_for_request, we just the 'namespace' keyword arguments to our queries:
Author.query(namespace=Author.ns).get()
Question: how to store (i.e. put()) the different kinds using these different namespaces? Something like:
# Not an API
Author().put(namespace=Author.ns)
Of course, the above doesn't work. (Yes, I could ask the datastore for an avaliable key in that namespace, and then use that key to store the instance with, but it's an extra API call that I'd like to avoid.)
To solve a problem like this I wrote a decorator as follows:
MY_NS = 'abc'
def in_my_namespace(fn):
"""Decorator: Run the given function in the MY_NS namespace"""
from google.appengine.api import namespace_manager
#functools.wraps(fn)
def wrapper(*args, **kwargs):
orig_ns = namespace_manager.get_namespace()
namespace_manager.set_namespace(MY_NS)
try:
res = fn(*args, **kwargs)
finally: # always drop out of the NS on the way up.
namespace_manager.set_namespace(orig_ns)
return res
return wrapper
So I can simply write, for functions that ought to occur in a separate namespace:
#in_my_namespace
def foo():
Author().put() # put into `my` namespace
Of course, applying this to a system to get the results you desire is a bit beyond the scope of this, but I thought it might be helpful.
EDIT: Using a with context
Here's how to accomplish the above using a with context:
class namespace_of(object):
def __init__(self, namespace):
self.ns = namespace
def __enter__(self):
self.orig_ns = namespace_manager.get_namespace()
namespace_manager.set_namespace(self.ns)
def __exit__(self, type, value, traceback):
namespace_manager.set_namespace(self.orig_ns)
Then elsewhere:
with namespace_of("Hello World"):
Author().put() # put into the `Hello World` namespace
A Model instance will use the namespace you set with the namespace_manager[1] as you can see here: python/google/appengine/ext/db/init.py
What you could do is create a child class of Model which expects a class-level 'ns' attribute to be defined. This sub class then overrides put() and sets the namespace before calling original put and resets the namespace afterwards. Something like this:
'''
class MyModel(db.Model):
ns = None
def put(*args, **kwargs):
if self.ns == None:
raise ValueError('"ns" is not defined for this class.')
original_namespace = namespace_manager.get_namespace()
try:
super(MyModelClass, self).put(*args, **kwargs)
finally:
namespace_manager.set_namespace(original_namespace)
'''
[1] http://code.google.com/appengine/docs/python/multitenancy/multitenancy.html
I don't think that it is possible to avoid the extra API call. Namespaces are encoded into the entity's Key, so in order to change the namespace within which a entity is stored, you need to create a new entity (that has a Key with the new namespace) and copy the old entity's data into it.

How ugly is my code implementing polymorphic models?

I am using Polymorphic Models.
Simple Question: My code below works without using this line below, which I see in other people's code. What is it supposed to do?
#super(GeneralModel, self).__init__(*args, **kwargs)
Messy Question: I have a feeling my code below, although it seems to work, is not the most beautiful solution.
Synopsis of what I am doing: I am instantiating (or making) a new datastore model entity based on a 'unclean' JSON object posted to the server. 1st I want to do some general input data cleaning specified in the general (or super) model and then 2nd do some special methods, which is specified in each special (or sub-class) model as def parse.
class GeneralModel(polymodel.PolyModel):
lat_long_list = db.ListProperty(db.GeoPt)
zooms = db.ListProperty(int)
def __init__(self, *args, **kwargs):
self.lat_long_list = [ db.GeoPt( pt[0] , pt[1] ) for pt in zip( kwargs["lat"] , kwargs["lon"] ) ]
del kwargs["lat"]
del kwargs["lon"]
if "zooms" not in kwargs: kwargs["zooms"] = ZOOMS # some default
for property,value in kwargs.items():
setattr(self,property,value)
#super(NamedModel, self).__init__(*args, **kwargs)
self.parse()
def parse(self):
raise NotImplementedError('Need to define this for each category')
class SpecialModel(GeneralModel):
stringText = db.StringProperty()
words_list = db.StringListProperty()
def parse( self ):
self.words_list = self.stringText.split(",")
This is how I test whether my code works:
>>>kwargs={'stringText':'boris,ted','lat':[0,1,2,3],'lon':[0,1,2,8],'zooms':[0,10]}
>>>entity=SpecialModel(key_name="tester",**kwargs)
>>>entity.words_list
['boris', 'ted']
The 'super' line calls the constructor of the parent entity. If you don't include it, the parent constructor will not be called, and your model will not be initialized properly. You should, in fact, be calling this first, before any of your own initialization.
However, overriding the constructor on models is strongly discouraged. The constructor is not just used when you call it, but also by the system to construct instances that are being loaded from the datastore, and in the latter case, the arguments - and the expected behaviour - are different, and implementation dependent.
Instead, you should probably define a factory method, like so:
class MyModel(db.PolyModel):
#classmethod
def create(cls, foo, bar):
# Do some stuff
return cls(foo, bleh)

Resources